mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
Merge pull request #3132 from eduar-hte/windows-port
Add support to build libModSecurity v3 on Windows
This commit is contained in:
commit
71a786b1e5
52
.github/workflows/ci.yml
vendored
52
.github/workflows/ci.yml
vendored
@ -72,3 +72,55 @@ jobs:
|
|||||||
run: make -j `sysctl -n hw.logicalcpu`
|
run: make -j `sysctl -n hw.logicalcpu`
|
||||||
- name: check
|
- name: check
|
||||||
run: make check
|
run: make check
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [windows-2022]
|
||||||
|
platform: [x86_64]
|
||||||
|
configuration: [Release]
|
||||||
|
configure:
|
||||||
|
- {label: "full", opt: "" }
|
||||||
|
- {label: "wo lmdb", opt: "-DWITHOUT_LMDB=ON" }
|
||||||
|
- {label: "wo lua", opt: "-DWITHOUT_LUA=ON" }
|
||||||
|
- {label: "wo maxmind", opt: "-DWITHOUT_MAXMIND=ON" }
|
||||||
|
- {label: "wo curl", opt: "-DWITHOUT_CURL=ON" }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
- name: Install Conan
|
||||||
|
run: |
|
||||||
|
pip3 install conan --upgrade
|
||||||
|
conan profile detect
|
||||||
|
- uses: ammaraskar/msvc-problem-matcher@master
|
||||||
|
- name: Build ${{ matrix.configuration }} ${{ matrix.platform }} ${{ matrix.configure.label }}
|
||||||
|
shell: cmd
|
||||||
|
run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform }} 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
|
||||||
|
257
Makefile.am
257
Makefile.am
@ -89,263 +89,8 @@ LOG_DRIVER = env $(SHELL) $(top_srcdir)/test/custom-test-driver
|
|||||||
AM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS;
|
AM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS;
|
||||||
LOG_COMPILER=test/test-suite.sh
|
LOG_COMPILER=test/test-suite.sh
|
||||||
|
|
||||||
# for i in `find test/test-cases -iname *.json`; do echo TESTS+=$i; done
|
|
||||||
TESTS=
|
TESTS=
|
||||||
TESTS+=test/test-cases/regression/action-allow.json
|
include test/test-suite.in
|
||||||
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/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
|
|
||||||
|
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = modsecurity.pc
|
pkgconfig_DATA = modsecurity.pc
|
||||||
|
244
build/win32/CMakeLists.txt
Normal file
244
build/win32/CMakeLists.txt
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.24)
|
||||||
|
|
||||||
|
set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||||
|
|
||||||
|
option(WITHOUT_LMDB "Include LMDB support" OFF)
|
||||||
|
option(WITHOUT_LUA "Include LUA support" OFF)
|
||||||
|
option(WITHOUT_LIBXML2 "Include LibXML2 support" OFF)
|
||||||
|
option(WITHOUT_MAXMIND "Include MaxMind support" OFF)
|
||||||
|
option(WITHOUT_CURL "Include CURL support" OFF)
|
||||||
|
|
||||||
|
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="mbed-tls-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)
|
||||||
|
|
||||||
|
add_library(libinjection STATIC ${BASE_DIR}/others/libinjection/src/libinjection_sqli.c ${BASE_DIR}/others/libinjection/src/libinjection_xss.c ${BASE_DIR}/others/libinjection/src/libinjection_html5.c)
|
||||||
|
|
||||||
|
# mbedtls
|
||||||
|
|
||||||
|
project(mbedtls C)
|
||||||
|
|
||||||
|
add_library(mbedtls STATIC ${BASE_DIR}/others/mbedtls/base64.c ${BASE_DIR}/others/mbedtls/sha1.c ${BASE_DIR}/others/mbedtls/md5.c)
|
||||||
|
|
||||||
|
target_include_directories(mbedtls PRIVATE ${BASE_DIR}/others)
|
||||||
|
|
||||||
|
#
|
||||||
|
# libModSecurity
|
||||||
|
#
|
||||||
|
|
||||||
|
project(libModSecurity
|
||||||
|
VERSION
|
||||||
|
3.0.12
|
||||||
|
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} 0)
|
||||||
|
else()
|
||||||
|
set(${flag} 1)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
enable_feature(HAVE_LMDB ${WITHOUT_LMDB})
|
||||||
|
enable_feature(HAVE_LUA ${WITHOUT_LUA})
|
||||||
|
enable_feature(HAVE_LIBXML2 ${WITHOUT_LIBXML2})
|
||||||
|
enable_feature(HAVE_MAXMIND ${WITHOUT_MAXMIND})
|
||||||
|
enable_feature(HAVE_CURL ${WITHOUT_CURL})
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake)
|
||||||
|
|
||||||
|
configure_file(config.h.cmake ${BASE_DIR}/src/config.h)
|
||||||
|
|
||||||
|
find_package(PCRE2 REQUIRED)
|
||||||
|
find_package(PThreads4W 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)
|
||||||
|
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 pthreads4w::pthreads4w libinjection mbedtls 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)
|
||||||
|
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})
|
||||||
|
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})
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
target_link_libraries(reading_logs_via_rule_message PRIVATE libModSecurity pthreads4w::pthreads4w)
|
||||||
|
|
||||||
|
# reading_logs_with_offset
|
||||||
|
add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc)
|
||||||
|
setExampleTargetProperties(reading_logs_with_offset)
|
||||||
|
|
||||||
|
# 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)
|
18
build/win32/ConfigureChecks.cmake
Normal file
18
build/win32/ConfigureChecks.cmake
Normal file
@ -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)
|
111
build/win32/README.md
Normal file
111
build/win32/README.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# libModSecurity Windows build information <!-- omit from toc -->
|
||||||
|
|
||||||
|
The Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for Visual C++ & CMake) and Conan package manager.
|
||||||
|
|
||||||
|
## Contents <!-- omit from toc -->
|
||||||
|
|
||||||
|
- [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.2.2](https://github.com/conan-io/conan/releases/download/2.2.2/conan-2.2.2-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.44.0](https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-64-bit.exe)
|
||||||
|
* To clone the libModSecurity repository.
|
||||||
|
* NOTE: Make sure to initialize and update submodules (to get `libinjection` and regression tests)
|
||||||
|
* `git submodule init`
|
||||||
|
* `git submodule update`
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Install the prerequisites listsed 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`
|
||||||
|
* 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.12.6 for XML processing support
|
||||||
|
* libcurl 8.6.0 to support http requests from rules
|
||||||
|
* libmaxminddb 1.9.1 to support reading MaxMind DB files.
|
||||||
|
* LUA 5.4.6 to enable rules to run scripts in this language for extensibility
|
||||||
|
* lmdb 0.9.31 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`
|
15
build/win32/conanfile.txt
Normal file
15
build/win32/conanfile.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[requires]
|
||||||
|
yajl/2.1.0
|
||||||
|
pcre2/10.42
|
||||||
|
pthreads4w/3.0.0
|
||||||
|
libxml2/2.12.6
|
||||||
|
lua/5.4.6
|
||||||
|
libcurl/8.6.0
|
||||||
|
lmdb/0.9.31
|
||||||
|
libmaxminddb/1.9.1
|
||||||
|
dirent/1.24
|
||||||
|
poco/1.13.3
|
||||||
|
|
||||||
|
[generators]
|
||||||
|
CMakeDeps
|
||||||
|
CMakeToolchain
|
92
build/win32/config.h.cmake
Normal file
92
build/win32/config.h.cmake
Normal file
@ -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 <dlfcn.h> header file. */
|
||||||
|
#cmakedefine HAVE_DLFCN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#cmakedefine HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <iostream> header file. */
|
||||||
|
#cmakedefine HAVE_IOSTREAM
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#cmakedefine HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdio.h> header file. */
|
||||||
|
#cmakedefine HAVE_STDIO_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#cmakedefine HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string> header file. */
|
||||||
|
#cmakedefine HAVE_STRING
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#cmakedefine HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#cmakedefine HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#cmakedefine HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#cmakedefine HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||||
|
#cmakedefine HAVE_SYS_UTSNAME_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> 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
|
115
build/win32/docker/Dockerfile
Normal file
115
build/win32/docker/Dockerfile
Normal file
@ -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.44.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.2.2
|
||||||
|
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 C:\src
|
||||||
|
|
||||||
|
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.7.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"]
|
17
build/win32/docker/InstallBuildTools.cmd
Normal file
17
build/win32/docker/InstallBuildTools.cmd
Normal file
@ -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!
|
||||||
|
)
|
||||||
|
)
|
20
build/win32/docker/git.inf
Normal file
20
build/win32/docker/git.inf
Normal file
@ -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
|
@ -19,7 +19,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -13,10 +13,11 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
|
||||||
#define NUM_THREADS 100
|
#define NUM_THREADS 100
|
||||||
@ -72,6 +73,11 @@ struct data_ms {
|
|||||||
modsecurity::RulesSet *rules;
|
modsecurity::RulesSet *rules;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4716) // avoid error C4716: 'process_request': must return a value, as MSVC C++ compiler doesn't support [[noreturn]]
|
||||||
|
#pragma warning(disable:4715) // avoid warning c4715: 'process_request' : not all control paths return a value
|
||||||
|
#endif
|
||||||
|
|
||||||
[[noreturn]] static void *process_request(void *data) {
|
[[noreturn]] static void *process_request(void *data) {
|
||||||
struct data_ms *a = (struct data_ms *)data;
|
struct data_ms *a = (struct data_ms *)data;
|
||||||
@ -85,7 +91,7 @@ struct data_ms {
|
|||||||
modsecTransaction->processConnection(ip, 12345, "127.0.0.1", 80);
|
modsecTransaction->processConnection(ip, 12345, "127.0.0.1", 80);
|
||||||
modsecTransaction->processURI(request_uri, "GET", "1.1");
|
modsecTransaction->processURI(request_uri, "GET", "1.1");
|
||||||
|
|
||||||
usleep(10);
|
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||||||
modsecTransaction->addRequestHeader("Host",
|
modsecTransaction->addRequestHeader("Host",
|
||||||
"net.tutsplus.com");
|
"net.tutsplus.com");
|
||||||
modsecTransaction->processRequestHeaders();
|
modsecTransaction->processRequestHeaders();
|
||||||
@ -105,6 +111,9 @@ struct data_ms {
|
|||||||
pthread_exit(nullptr);
|
pthread_exit(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
class ReadingLogsViaRuleMessage {
|
class ReadingLogsViaRuleMessage {
|
||||||
public:
|
public:
|
||||||
@ -151,7 +160,7 @@ class ReadingLogsViaRuleMessage {
|
|||||||
reinterpret_cast<void *>(&dms));
|
reinterpret_cast<void *>(&dms));
|
||||||
}
|
}
|
||||||
|
|
||||||
usleep(10000);
|
std::this_thread::sleep_for(std::chrono::microseconds(10000));
|
||||||
|
|
||||||
for (i=0; i < NUM_THREADS; i++) {
|
for (i=0; i < NUM_THREADS; i++) {
|
||||||
pthread_join(threads[i], &status);
|
pthread_join(threads[i], &status);
|
||||||
|
@ -13,7 +13,11 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -37,7 +37,11 @@ bool SetENV::evaluate(RuleWithActions *rule, Transaction *t) {
|
|||||||
auto pair = utils::string::ssplit_pair(colNameExpanded, '=');
|
auto pair = utils::string::ssplit_pair(colNameExpanded, '=');
|
||||||
ms_dbg_a(t, 8, "Setting environment variable: "
|
ms_dbg_a(t, 8, "Setting environment variable: "
|
||||||
+ pair.first + " to " + pair.second);
|
+ pair.first + " to " + pair.second);
|
||||||
|
#ifndef WIN32
|
||||||
setenv(pair.first.c_str(), pair.second.c_str(), /*overwrite*/ 1);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
#include "src/actions/transformations/transformation.h"
|
#include "src/actions/transformations/transformation.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace actions {
|
namespace actions {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
#include "src/actions/transformations/transformation.h"
|
#include "src/actions/transformations/transformation.h"
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
#include "src/actions/transformations/transformation.h"
|
#include "src/actions/transformations/transformation.h"
|
||||||
|
@ -21,7 +21,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
* directly using the email address security@modsecurity.org.
|
* directly using the email address security@modsecurity.org.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -18,7 +18,11 @@
|
|||||||
#include "src/collection/backend/collection_data.h"
|
#include "src/collection/backend/collection_data.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
22
src/compat/msvc.h
Normal file
22
src/compat/msvc.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __COMPAT_MSVC
|
||||||
|
#define __COMPAT_MSVC
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#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) {
|
||||||
|
if (!localtime_s(tout, tin)) return tout;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -15,10 +15,6 @@
|
|||||||
|
|
||||||
#include "modsecurity/debug_log.h"
|
#include "modsecurity/debug_log.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "src/debug_log/debug_log_writer.h"
|
#include "src/debug_log/debug_log_writer.h"
|
||||||
#include "src/debug_log_writer_agent.h"
|
#include "src/debug_log_writer_agent.h"
|
||||||
|
|
||||||
|
@ -15,18 +15,6 @@
|
|||||||
|
|
||||||
#include "src/debug_log/debug_log_writer.h"
|
#include "src/debug_log/debug_log_writer.h"
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "src/utils/shared_files.h"
|
#include "src/utils/shared_files.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
|
@ -13,15 +13,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SRC_DEBUG_LOG_DEBUG_LOG_WRITER_H_
|
#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);
|
static int open(const std::string& m_fileName, std::string *error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebugLogWriter() : m_first(NULL) { }
|
DebugLogWriter() = default;
|
||||||
~DebugLogWriter() { }
|
~DebugLogWriter() = default;
|
||||||
|
|
||||||
// C++ 03
|
// C++ 03
|
||||||
// ========
|
// ========
|
||||||
// Dont forget to declare these two. You want to make sure they
|
// Dont forget to declare these two. You want to make sure they
|
||||||
// are unacceptable otherwise you may accidentally get copies of
|
// are unacceptable otherwise you may accidentally get copies of
|
||||||
// your singleton appearing.
|
// your singleton appearing.
|
||||||
DebugLogWriter(DebugLogWriter const&);
|
DebugLogWriter(DebugLogWriter const&) = delete;
|
||||||
void operator=(DebugLogWriter const&);
|
void operator=(DebugLogWriter const&) = delete;
|
||||||
|
|
||||||
struct debug_log_file_handler *m_first;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -258,14 +258,11 @@ int ModSecurity::processContentOffset(const char *content, size_t len,
|
|||||||
strlen("highlight"));
|
strlen("highlight"));
|
||||||
|
|
||||||
yajl_gen_array_open(g);
|
yajl_gen_array_open(g);
|
||||||
while (vars.size() > 3) {
|
for(auto [it, pending] = std::tuple{vars.rbegin(), vars.size()}; pending > 3; pending -= 3) {
|
||||||
std::string value;
|
|
||||||
yajl_gen_map_open(g);
|
yajl_gen_map_open(g);
|
||||||
vars.pop_back();
|
it++;
|
||||||
const std::string &startingAt = vars.back().str();
|
const std::string &startingAt = it->str(); it++;
|
||||||
vars.pop_back();
|
const std::string &size = it->str(); it++;
|
||||||
const std::string &size = vars.back().str();
|
|
||||||
vars.pop_back();
|
|
||||||
yajl_gen_string(g,
|
yajl_gen_string(g,
|
||||||
reinterpret_cast<const unsigned char*>("startingAt"),
|
reinterpret_cast<const unsigned char*>("startingAt"),
|
||||||
strlen("startingAt"));
|
strlen("startingAt"));
|
||||||
@ -284,7 +281,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = std::string(content, stoi(startingAt), stoi(size));
|
const auto value = std::string(content, stoi(startingAt), stoi(size));
|
||||||
if (varValue.size() > 0) {
|
if (varValue.size() > 0) {
|
||||||
varValue.append(" " + value);
|
varValue.append(" " + value);
|
||||||
} else {
|
} else {
|
||||||
@ -340,16 +337,13 @@ int ModSecurity::processContentOffset(const char *content, size_t len,
|
|||||||
|
|
||||||
yajl_gen_map_open(g);
|
yajl_gen_map_open(g);
|
||||||
|
|
||||||
while (ops.size() > 3) {
|
for(auto [it, pending] = std::tuple{ops.rbegin(), ops.size()}; pending > 3; pending -= 3) {
|
||||||
std::string value;
|
|
||||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>("highlight"),
|
yajl_gen_string(g, reinterpret_cast<const unsigned char*>("highlight"),
|
||||||
strlen("highlight"));
|
strlen("highlight"));
|
||||||
yajl_gen_map_open(g);
|
yajl_gen_map_open(g);
|
||||||
ops.pop_back();
|
it++;
|
||||||
std::string startingAt = ops.back().str();
|
const std::string &startingAt = it->str(); it++;
|
||||||
ops.pop_back();
|
const std::string &size = ops.back().str(); it++;
|
||||||
std::string size = ops.back().str();
|
|
||||||
ops.pop_back();
|
|
||||||
yajl_gen_string(g,
|
yajl_gen_string(g,
|
||||||
reinterpret_cast<const unsigned char*>("startingAt"),
|
reinterpret_cast<const unsigned char*>("startingAt"),
|
||||||
strlen("startingAt"));
|
strlen("startingAt"));
|
||||||
@ -371,7 +365,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len,
|
|||||||
reinterpret_cast<const unsigned char*>("value"),
|
reinterpret_cast<const unsigned char*>("value"),
|
||||||
strlen("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,
|
yajl_gen_string(g,
|
||||||
reinterpret_cast<const unsigned char*>(value.c_str()),
|
reinterpret_cast<const unsigned char*>(value.c_str()),
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
#include "src/operators/operator.h"
|
#include "src/operators/operator.h"
|
||||||
#include "src/utils/system.h"
|
#include "src/utils/system.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace operators {
|
namespace operators {
|
||||||
|
|
||||||
|
@ -16,10 +16,15 @@
|
|||||||
#include "src/operators/rbl.h"
|
#include "src/operators/rbl.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#else
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#include <WS2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -17,10 +17,14 @@
|
|||||||
#define SRC_OPERATORS_RBL_H_
|
#define SRC_OPERATORS_RBL_H_
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#else
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -4952,7 +4952,11 @@ static std::stack<int> YY_PREVIOUS_STATE;
|
|||||||
* The user has a chance to override it with an option.
|
* The user has a chance to override it with an option.
|
||||||
*/
|
*/
|
||||||
/* %if-c-only */
|
/* %if-c-only */
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
/* %endif */
|
/* %endif */
|
||||||
/* %if-c++-only */
|
/* %if-c++-only */
|
||||||
/* %endif */
|
/* %endif */
|
||||||
|
@ -21,7 +21,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -61,12 +66,11 @@ MultipartPartTmpFile::~MultipartPartTmpFile() {
|
|||||||
|
|
||||||
void MultipartPartTmpFile::Open() {
|
void MultipartPartTmpFile::Open() {
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
char tstr[300];
|
|
||||||
time_t tt = time(NULL);
|
time_t tt = time(NULL);
|
||||||
|
|
||||||
localtime_r(&tt, &timeinfo);
|
localtime_r(&tt, &timeinfo);
|
||||||
|
|
||||||
memset(tstr, '\0', 300);
|
char tstr[300] {};
|
||||||
strftime(tstr, 299, "/%Y%m%d-%H%M%S", &timeinfo);
|
strftime(tstr, 299, "/%Y%m%d-%H%M%S", &timeinfo);
|
||||||
|
|
||||||
std::string path = m_transaction->m_rules->m_uploadDirectory.m_value;
|
std::string path = m_transaction->m_rules->m_uploadDirectory.m_value;
|
||||||
@ -74,14 +78,23 @@ void MultipartPartTmpFile::Open() {
|
|||||||
path += "-file-XXXXXX";
|
path += "-file-XXXXXX";
|
||||||
|
|
||||||
char* tmp = strdup(path.c_str());
|
char* tmp = strdup(path.c_str());
|
||||||
|
#ifndef WIN32
|
||||||
m_tmp_file_fd = mkstemp(tmp);
|
m_tmp_file_fd = mkstemp(tmp);
|
||||||
|
#else
|
||||||
|
_mktemp_s(tmp, path.length()+1);
|
||||||
|
m_tmp_file_fd = _open(tmp, _O_CREAT | _O_EXCL | _O_RDWR);
|
||||||
|
#endif
|
||||||
m_tmp_file_name.assign(tmp);
|
m_tmp_file_name.assign(tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
ms_dbg_a(m_transaction, 4, "MultipartPartTmpFile: Create filename= " + m_tmp_file_name);
|
ms_dbg_a(m_transaction, 4, "MultipartPartTmpFile: Create filename= " + m_tmp_file_name);
|
||||||
|
|
||||||
int mode = m_transaction->m_rules->m_uploadFileMode.m_value;
|
int mode = m_transaction->m_rules->m_uploadFileMode.m_value;
|
||||||
if ((m_tmp_file_fd != -1) && (mode != 0)) {
|
if ((m_tmp_file_fd != -1) && (mode != 0)) {
|
||||||
|
#ifndef WIN32
|
||||||
if (fchmod(m_tmp_file_fd, mode) == -1) {
|
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;
|
m_tmp_file_fd = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,9 +172,7 @@ RuleWithActions::~RuleWithActions() {
|
|||||||
|
|
||||||
|
|
||||||
bool RuleWithActions::evaluate(Transaction *transaction) {
|
bool RuleWithActions::evaluate(Transaction *transaction) {
|
||||||
RuleMessage rm(this, transaction);
|
return evaluate(transaction, std::make_shared<RuleMessage>(this, transaction));
|
||||||
std::shared_ptr<RuleMessage> rm2 = std::make_shared<RuleMessage>(&rm);
|
|
||||||
return evaluate(transaction, rm2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -330,7 +328,7 @@ inline void RuleWithActions::executeTransformation(
|
|||||||
std::string newValue = a->evaluate(*oldValue, trans);
|
std::string newValue = a->evaluate(*oldValue, trans);
|
||||||
|
|
||||||
if (newValue != *oldValue) {
|
if (newValue != *oldValue) {
|
||||||
std::shared_ptr<std::string> u(new std::string(newValue));
|
auto u = std::make_shared<std::string>(newValue);
|
||||||
if (m_containsMultiMatchAction) {
|
if (m_containsMultiMatchAction) {
|
||||||
ret->push_back(std::make_pair(u, a->m_name));
|
ret->push_back(std::make_pair(u, a->m_name));
|
||||||
(*nth)++;
|
(*nth)++;
|
||||||
@ -355,14 +353,13 @@ void RuleWithActions::executeTransformations(
|
|||||||
int none = 0;
|
int none = 0;
|
||||||
int transformations = 0;
|
int transformations = 0;
|
||||||
std::string path("");
|
std::string path("");
|
||||||
std::shared_ptr<std::string> value =
|
auto value = std::make_shared<std::string>(in);
|
||||||
std::shared_ptr<std::string>(new std::string(in));
|
|
||||||
|
|
||||||
if (m_containsMultiMatchAction == true) {
|
if (m_containsMultiMatchAction == true) {
|
||||||
/* keep the original value */
|
/* keep the original value */
|
||||||
ret.push_back(std::make_pair(
|
ret.push_back(std::make_pair(
|
||||||
std::shared_ptr<std::string>(new std::string(*value)),
|
std::make_shared<std::string>(*value),
|
||||||
std::shared_ptr<std::string>(new std::string(path))));
|
std::make_shared<std::string>(path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Action *a : m_transformations) {
|
for (Action *a : m_transformations) {
|
||||||
@ -436,8 +433,8 @@ void RuleWithActions::executeTransformations(
|
|||||||
|
|
||||||
if (!m_containsMultiMatchAction) {
|
if (!m_containsMultiMatchAction) {
|
||||||
ret.push_back(std::make_pair(
|
ret.push_back(std::make_pair(
|
||||||
std::shared_ptr<std::string>(new std::string(*value)),
|
std::make_shared<std::string>(*value),
|
||||||
std::shared_ptr<std::string>(new std::string(path))));
|
std::make_shared<std::string>(path)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#include "src/utils/string.h"
|
#include "src/utils/string.h"
|
||||||
#include "src/variables/variable.h"
|
#include "src/variables/variable.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@
|
|||||||
#include "src/actions/disruptive/allow.h"
|
#include "src/actions/disruptive/allow.h"
|
||||||
#include "src/variables/remote_user.h"
|
#include "src/variables/remote_user.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using modsecurity::actions::Action;
|
using modsecurity::actions::Action;
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
#include "src/config.h"
|
#include "src/config.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <winsock2.h>
|
#include "src/compat/msvc.h"
|
||||||
|
#include <WinSock2.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -48,7 +49,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "src/utils/sha1.h"
|
#include "src/utils/sha1.h"
|
||||||
@ -207,7 +212,7 @@ std::string UniqueId::ethernetMacAddress() {
|
|||||||
pAdapter = pAdapterInfo;
|
pAdapter = pAdapterInfo;
|
||||||
while (pAdapter && !mac[0] && !mac[1] && !mac[2]) {
|
while (pAdapter && !mac[0] && !mac[1] && !mac[2]) {
|
||||||
if (pAdapter->AddressLength > 4) {
|
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[0],
|
||||||
(unsigned char)pAdapter->Address[1],
|
(unsigned char)pAdapter->Address[1],
|
||||||
(unsigned char)pAdapter->Address[2],
|
(unsigned char)pAdapter->Address[2],
|
||||||
|
@ -13,10 +13,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#else
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -20,10 +20,14 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#else
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -94,6 +98,11 @@ bool HttpsClient::download(const std::string &uri) {
|
|||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
|
||||||
|
|
||||||
|
#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 */
|
/* send all data to this function */
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle);
|
||||||
|
|
||||||
|
@ -15,10 +15,14 @@
|
|||||||
|
|
||||||
#include "src/utils/ip_tree.h"
|
#include "src/utils/ip_tree.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#else
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -15,9 +15,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#else
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#include <WS2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "src/utils/msc_tree.h"
|
#include "src/utils/msc_tree.h"
|
||||||
|
|
||||||
|
@ -15,236 +15,103 @@
|
|||||||
|
|
||||||
#include "src/utils/shared_files.h"
|
#include "src/utils/shared_files.h"
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#ifdef WIN32
|
||||||
#include <stdio.h>
|
#include <windows.h>
|
||||||
#include <sys/ipc.h>
|
#include <io.h>
|
||||||
#include <sys/shm.h>
|
#endif
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
|
||||||
std::pair<msc_file_handler *, FILE *> SharedFiles::find_handler(
|
SharedFiles::handlers_map::iterator SharedFiles::add_new_handler(
|
||||||
const std::string &fileName) {
|
|
||||||
for (const auto &i : m_handlers) {
|
|
||||||
if (i.first == fileName) {
|
|
||||||
return i.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::pair<modsecurity::utils::msc_file_handler *,
|
|
||||||
FILE *>(NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::pair<msc_file_handler *, FILE *> SharedFiles::add_new_handler(
|
|
||||||
const std::string &fileName, std::string *error) {
|
const std::string &fileName, std::string *error) {
|
||||||
int shm_id;
|
FILE *fp = fopen(fileName.c_str(), "a");
|
||||||
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");
|
|
||||||
if (fp == 0) {
|
if (fp == 0) {
|
||||||
error->assign("Failed to open file: " + fileName);
|
error->assign("Failed to open file: " + fileName);
|
||||||
goto err_fh;
|
return m_handlers.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_key_structure = ftok(fileName.c_str(), 1);
|
return m_handlers.insert({ fileName, {fp, 0} }).first;
|
||||||
if (mem_key_structure < 0) {
|
|
||||||
error->assign("Failed to select key for the shared memory (1): ");
|
|
||||||
error->append(strerror(errno));
|
|
||||||
goto err_mem_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_debug_log = reinterpret_cast<msc_file_handler_t *>(
|
|
||||||
shmat(shm_id, NULL, 0));
|
|
||||||
if ((reinterpret_cast<char *>(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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<modsecurity::utils::msc_file_handler *,
|
|
||||||
FILE *>(NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SharedFiles::open(const std::string& fileName, std::string *error) {
|
bool SharedFiles::open(const std::string& fileName, std::string *error) {
|
||||||
std::pair<msc_file_handler *, FILE *> a;
|
auto it = m_handlers.find(fileName);
|
||||||
bool ret = true;
|
if (it == m_handlers.end()) {
|
||||||
|
it = add_new_handler(fileName, error);
|
||||||
#if MODSEC_USE_GENERAL_LOCK
|
if (error->size() > 0)
|
||||||
pthread_mutex_lock(m_generalLock);
|
return false;
|
||||||
#endif
|
|
||||||
|
|
||||||
a = find_handler(fileName);
|
|
||||||
if (a.first == NULL) {
|
|
||||||
a = add_new_handler(fileName, error);
|
|
||||||
if (error->size() > 0) {
|
|
||||||
ret = false;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (a.first == NULL) {
|
|
||||||
|
if (it == m_handlers.end()) {
|
||||||
error->assign("Not able to open: " + fileName);
|
error->assign("Not able to open: " + fileName);
|
||||||
ret = false;
|
return false;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
it->second.cnt++;
|
||||||
#if MODSEC_USE_GENERAL_LOCK
|
|
||||||
pthread_mutex_unlock(m_generalLock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SharedFiles::close(const std::string& fileName) {
|
void SharedFiles::close(const std::string& fileName) {
|
||||||
std::pair<msc_file_handler *, FILE *> a;
|
if (fileName.empty())
|
||||||
/* int ret; */
|
return;
|
||||||
/* int shm_id; */
|
|
||||||
/* struct shmid_ds shared_mem_info; */
|
|
||||||
/* int j = 0; */
|
|
||||||
|
|
||||||
#if MODSEC_USE_GENERAL_LOCK
|
auto it = m_handlers.find(fileName);
|
||||||
pthread_mutex_lock(m_generalLock);
|
if (it == m_handlers.end())
|
||||||
#endif
|
return;
|
||||||
|
|
||||||
if (fileName.empty()) {
|
it->second.cnt--;
|
||||||
goto out;
|
if (it->second.cnt == 0)
|
||||||
|
{
|
||||||
|
fclose(it->second.fp);
|
||||||
|
|
||||||
|
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<std::string,
|
|
||||||
std::pair<msc_file_handler *, FILE *>> 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,
|
bool SharedFiles::write(const std::string& fileName,
|
||||||
const std::string &msg, std::string *error) {
|
const std::string &msg, std::string *error) {
|
||||||
std::pair<msc_file_handler *, FILE *> a;
|
|
||||||
std::string lmsg = msg;
|
|
||||||
size_t wrote;
|
|
||||||
struct flock lock{};
|
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
a = find_handler(fileName);
|
auto it = m_handlers.find(fileName);
|
||||||
if (a.first == NULL) {
|
if (it == m_handlers.end()) {
|
||||||
error->assign("file is not open: " + fileName);
|
error->assign("file is not open: " + fileName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Exclusively lock whole file
|
//Exclusively lock whole file
|
||||||
|
#ifndef WIN32
|
||||||
|
struct flock lock {};
|
||||||
lock.l_start = lock.l_len = lock.l_whence = 0;
|
lock.l_start = lock.l_len = lock.l_whence = 0;
|
||||||
lock.l_type = F_WRLCK;
|
lock.l_type = F_WRLCK;
|
||||||
fcntl(fileno(a.second), F_SETLKW, &lock);
|
fcntl(fileno(it->second.fp), F_SETLKW, &lock);
|
||||||
|
#else
|
||||||
|
auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fileno(it->second.fp)));
|
||||||
|
OVERLAPPED overlapped = { 0 };
|
||||||
|
::LockFileEx(handle, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &overlapped);
|
||||||
|
#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()) {
|
if (wrote < msg.size()) {
|
||||||
error->assign("failed to write: " + fileName);
|
error->assign("failed to write: " + fileName);
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
fflush(a.second);
|
fflush(it->second.fp);
|
||||||
|
|
||||||
//Remove exclusive lock
|
//Remove exclusive lock
|
||||||
|
#ifndef WIN32
|
||||||
lock.l_type = F_UNLCK;
|
lock.l_type = F_UNLCK;
|
||||||
fcntl(fileno(a.second), F_SETLKW, &lock);
|
fcntl(fileno(it->second.fp), F_SETLKW, &lock);
|
||||||
|
#else
|
||||||
|
overlapped = { 0 };
|
||||||
|
::UnlockFileEx(handle, 0, MAXDWORD, MAXDWORD, &overlapped);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -17,45 +17,18 @@
|
|||||||
#define SRC_UTILS_SHARED_FILES_H_
|
#define SRC_UTILS_SHARED_FILES_H_
|
||||||
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <utility>
|
#include <unordered_map>
|
||||||
#include <vector>
|
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
|
||||||
#include "modsecurity/audit_log.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not using this critical section yet.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* #define MODSEC_USE_GENERAL_LOCK */
|
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
|
||||||
typedef struct msc_file_handler {
|
|
||||||
int shm_id_structure;
|
|
||||||
char file_name[];
|
|
||||||
} msc_file_handler_t;
|
|
||||||
|
|
||||||
|
|
||||||
class SharedFiles {
|
class SharedFiles {
|
||||||
public:
|
public:
|
||||||
bool open(const std::string& fileName, std::string *error);
|
bool open(const std::string& fileName, std::string *error);
|
||||||
void close(const std::string& fileName);
|
void close(const std::string& fileName);
|
||||||
bool write(const std::string& fileName, const std::string &msg,
|
bool write(const std::string& fileName, const std::string &msg,
|
||||||
@ -66,86 +39,28 @@ class SharedFiles {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
std::pair<msc_file_handler *, FILE *> find_handler(
|
SharedFiles() = default;
|
||||||
const std::string &fileName);
|
~SharedFiles() = default;
|
||||||
std::pair<msc_file_handler *, FILE *> 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); // cppcheck-suppress useInitializationList
|
|
||||||
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<pthread_mutex_t *>(
|
|
||||||
shmat(shm_id, NULL, 0));
|
|
||||||
if ((reinterpret_cast<char *>(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
|
|
||||||
}
|
|
||||||
|
|
||||||
// C++ 03
|
// C++ 03
|
||||||
// ========
|
// ========
|
||||||
// Dont forget to declare these two. You want to make sure they
|
// Dont forget to declare these two. You want to make sure they
|
||||||
// are unacceptable otherwise you may accidentally get copies of
|
// are unacceptable otherwise you may accidentally get copies of
|
||||||
// your singleton appearing.
|
// your singleton appearing.
|
||||||
SharedFiles(SharedFiles const&);
|
SharedFiles(SharedFiles const&) = delete;
|
||||||
void operator=(SharedFiles const&);
|
void operator=(SharedFiles const&) = delete;
|
||||||
|
|
||||||
std::vector<std::pair<std::string,
|
struct handler_info {
|
||||||
std::pair<msc_file_handler *, FILE *>>> m_handlers;
|
FILE* fp;
|
||||||
#if MODSEC_USE_GENERAL_LOCK
|
unsigned int cnt;
|
||||||
pthread_mutex_t *m_generalLock;
|
};
|
||||||
key_t m_memKeyStructure;
|
|
||||||
#endif
|
using handlers_map = std::unordered_map<std::string, handler_info>;
|
||||||
|
handlers_map m_handlers;
|
||||||
|
|
||||||
|
handlers_map::iterator add_new_handler(
|
||||||
|
const std::string &fileName, std::string *error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,11 +17,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef __OpenBSD__
|
|
||||||
#include <glob.h>
|
|
||||||
#else
|
|
||||||
#include <wordexp.h>
|
|
||||||
#endif
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
#elif defined(WIN32)
|
||||||
|
#include "Poco/Glob.h"
|
||||||
|
#include <algorithm>
|
||||||
#else
|
#else
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
#endif
|
#endif
|
||||||
@ -31,6 +34,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined _MSC_VER
|
#if defined _MSC_VER
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#elif defined __GNUC__
|
#elif defined __GNUC__
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -40,6 +44,36 @@
|
|||||||
#include "src/utils/system.h"
|
#include "src/utils/system.h"
|
||||||
#include "src/config.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 modsecurity {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
@ -64,19 +98,15 @@ double cpu_seconds(void) {
|
|||||||
|
|
||||||
std::string find_resource(const std::string& resource,
|
std::string find_resource(const std::string& resource,
|
||||||
const std::string& config, std::string *err) {
|
const std::string& config, std::string *err) {
|
||||||
std::ifstream *iss;
|
|
||||||
|
|
||||||
err->assign("Looking at: ");
|
err->assign("Looking at: ");
|
||||||
// Trying absolute or relative to the current dir.
|
// Trying absolute or relative to the current dir.
|
||||||
iss = new std::ifstream(resource, std::ios::in);
|
auto iss = std::ifstream(resource, std::ios::in);
|
||||||
if (iss->is_open()) {
|
if (iss.is_open()) {
|
||||||
iss->close();
|
|
||||||
delete iss;
|
|
||||||
return resource;
|
return resource;
|
||||||
} else {
|
} else {
|
||||||
err->append("'" + resource + "', ");
|
err->append("'" + resource + "', ");
|
||||||
}
|
}
|
||||||
delete iss;
|
|
||||||
|
|
||||||
// What about `*' ?
|
// What about `*' ?
|
||||||
if (utils::expandEnv(resource, 0).size() > 0) {
|
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.
|
// Trying the same path of the configuration file.
|
||||||
std::string f = get_path(config) + "/" + resource;
|
std::string f = get_path(config) + "/" + resource;
|
||||||
iss = new std::ifstream(f, std::ios::in);
|
iss = std::ifstream(f, std::ios::in);
|
||||||
if (iss->is_open()) {
|
if (iss.is_open()) {
|
||||||
iss->close();
|
|
||||||
delete iss;
|
|
||||||
return f;
|
return f;
|
||||||
} else {
|
} else {
|
||||||
err->append("'" + f + "', ");
|
err->append("'" + f + "', ");
|
||||||
}
|
}
|
||||||
delete iss;
|
|
||||||
|
|
||||||
// What about `*' ?
|
// What about `*' ?
|
||||||
if (utils::expandEnv(f, 0).size() > 0) {
|
if (utils::expandEnv(f, 0).size() > 0) {
|
||||||
@ -122,8 +149,16 @@ std::string get_path(const std::string& file) {
|
|||||||
|
|
||||||
std::list<std::string> expandEnv(const std::string& var, int flags) {
|
std::list<std::string> expandEnv(const std::string& var, int flags) {
|
||||||
std::list<std::string> vars;
|
std::list<std::string> vars;
|
||||||
|
#ifdef WIN32
|
||||||
#ifdef __OpenBSD__
|
// NOTE: align scopes with if & if in other versions
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::set<std::string> 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;
|
glob_t p;
|
||||||
if (glob(var.c_str(), flags, NULL, &p) == false) {
|
if (glob(var.c_str(), flags, NULL, &p) == false) {
|
||||||
if (p.gl_pathc) {
|
if (p.gl_pathc) {
|
||||||
@ -135,15 +170,13 @@ std::list<std::string> expandEnv(const std::string& var, int flags) {
|
|||||||
if (p.we_wordc) {
|
if (p.we_wordc) {
|
||||||
for (char** exp = p.we_wordv; *exp; ++exp) {
|
for (char** exp = p.we_wordv; *exp; ++exp) {
|
||||||
#endif
|
#endif
|
||||||
std::ifstream *iss = new std::ifstream(exp[0], std::ios::in);
|
auto iss = std::ifstream(exp[0], std::ios::in);
|
||||||
if (iss->is_open()) {
|
if (iss.is_open())
|
||||||
iss->close();
|
|
||||||
vars.push_back(exp[0]);
|
vars.push_back(exp[0]);
|
||||||
}
|
|
||||||
delete iss;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef __OpenBSD__
|
#ifdef WIN32
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
globfree(&p);
|
globfree(&p);
|
||||||
#else
|
#else
|
||||||
wordfree(&p);
|
wordfree(&p);
|
||||||
@ -153,7 +186,13 @@ std::list<std::string> expandEnv(const std::string& var, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool createDir(const std::string& dir, int mode, std::string *error) {
|
bool createDir(const std::string& dir, int mode, std::string *error) {
|
||||||
|
#ifndef WIN32
|
||||||
int ret = mkdir(dir.data(), mode);
|
int ret = mkdir(dir.data(), mode);
|
||||||
|
#else
|
||||||
|
if (dir == ".")
|
||||||
|
return true;
|
||||||
|
int ret = _mkdir(dir.c_str());
|
||||||
|
#endif
|
||||||
if (ret != 0 && errno != EEXIST) {
|
if (ret != 0 && errno != EEXIST) {
|
||||||
error->assign("Not able to create directory: " + dir + ": " \
|
error->assign("Not able to create directory: " + dir + ": " \
|
||||||
+ strerror(errno) + ".");
|
+ strerror(errno) + ".");
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
@ -25,9 +25,15 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
@ -47,12 +53,20 @@ void Env::evaluate(Transaction *transaction,
|
|||||||
transaction->m_variableEnvs.insert(a);
|
transaction->m_variableEnvs.insert(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto hasName = m_name.length() > 0;
|
||||||
for (auto& x : transaction->m_variableEnvs) {
|
for (auto& x : transaction->m_variableEnvs) {
|
||||||
if (x.first != m_name && m_name.length() > 0) {
|
#ifndef WIN32
|
||||||
|
if (hasName && x.first != m_name) {
|
||||||
|
#else
|
||||||
|
if (hasName && strcasecmp(x.first.c_str(), m_name.c_str()) != 0) {
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!m_keyExclusion.toOmit(x.first)) {
|
// (Windows) we need to keep the case from the rule in case that from
|
||||||
l->push_back(new VariableValue(&m_collectionName, &x.first,
|
// 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));
|
&x.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "src/compat/msvc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace variables {
|
namespace variables {
|
||||||
|
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git owasp-v2
|
git clone https://github.com/coreruleset/coreruleset.git owasp-v2
|
||||||
|
cd owasp-v2
|
||||||
|
git checkout 2.2.9 -b tag2.2.9
|
||||||
|
cd -
|
||||||
|
|
||||||
echo 'Include "owasp-v2/base_rules/*.conf"' >> basic_rules.conf
|
echo 'Include "owasp-v2/base_rules/*.conf"' >> basic_rules.conf
|
||||||
echo 'Include "owasp-v2/optional_rules/*.conf"' >> basic_rules.conf
|
echo 'Include "owasp-v2/optional_rules/*.conf"' >> basic_rules.conf
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git owasp-v3
|
git clone https://github.com/coreruleset/coreruleset.git owasp-v3
|
||||||
cd owasp-v3
|
cd owasp-v3
|
||||||
git checkout v3.0.2 -b tag3.0.2
|
git checkout v3.0.2 -b tag3.0.2
|
||||||
cd -
|
cd -
|
||||||
|
@ -42,9 +42,9 @@ print_usage ()
|
|||||||
{
|
{
|
||||||
cat <<END
|
cat <<END
|
||||||
Usage:
|
Usage:
|
||||||
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
|
test-driver --test-name NAME --log-file PATH --trs-file PATH
|
||||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
[--expect-failure {yes|no}] [--color-tests {yes|no}]
|
||||||
[--enable-hard-errors={yes|no}] [--]
|
[--enable-hard-errors {yes|no}] [--]
|
||||||
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
||||||
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
||||||
END
|
END
|
||||||
|
@ -114,7 +114,11 @@ using namespace modsecurity;
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -60,13 +64,11 @@ bool contains(const std::string &s, const std::string &pattern) {
|
|||||||
|
|
||||||
void clearAuditLog(const std::string &filename) {
|
void clearAuditLog(const std::string &filename) {
|
||||||
if (!filename.empty()) {
|
if (!filename.empty()) {
|
||||||
std::ifstream file;
|
std::ofstream file{filename.c_str(), std::ofstream::out | std::ofstream::trunc};
|
||||||
file.open(filename.c_str(), std::ifstream::out | std::ifstream::trunc);
|
|
||||||
if (!file.is_open() || file.fail()) {
|
if (!file.is_open() || file.fail()) {
|
||||||
std::cout << std::endl << "Failed to clear previous contents of audit log: " \
|
std::cout << std::endl << "Failed to clear previous contents of audit log: " \
|
||||||
<< filename << std::endl;
|
<< filename << std::endl;
|
||||||
}
|
}
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string getAuditLogContent(const std::string &filename) {
|
std::string getAuditLogContent(const std::string &filename) {
|
||||||
@ -506,6 +508,7 @@ int main(int argc, char **argv) {
|
|||||||
#ifdef NO_LOGS
|
#ifdef NO_LOGS
|
||||||
std::cout << "Test utility cannot work without logging support." \
|
std::cout << "Test utility cannot work without logging support." \
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
test.cmd_options(argc, argv);
|
test.cmd_options(argc, argv);
|
||||||
if (!test.m_automake_output && !test.m_count_all) {
|
if (!test.m_automake_output && !test.m_count_all) {
|
||||||
@ -605,6 +608,6 @@ int main(int argc, char **argv) {
|
|||||||
delete vec;
|
delete vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return failed;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,6 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"expected":{
|
"expected":{
|
||||||
// should not match
|
|
||||||
},
|
},
|
||||||
"rules":[
|
"rules":[
|
||||||
"SecRequestBodyAccess On",
|
"SecRequestBodyAccess On",
|
||||||
@ -248,7 +247,6 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"expected":{
|
"expected":{
|
||||||
// should not match
|
|
||||||
},
|
},
|
||||||
"rules":[
|
"rules":[
|
||||||
"SecRequestBodyAccess On",
|
"SecRequestBodyAccess On",
|
||||||
|
255
test/test-suite.in
Normal file
255
test/test-suite.in
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
# 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/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
|
@ -13,7 +13,7 @@ then
|
|||||||
AMOUNT=$(./regression_tests countall ../$FILE)
|
AMOUNT=$(./regression_tests countall ../$FILE)
|
||||||
RET=$?
|
RET=$?
|
||||||
if [ $RET -ne 0 ]; then
|
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
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -30,10 +30,10 @@ else
|
|||||||
RET=$?
|
RET=$?
|
||||||
if [ $RET -eq 127 ]
|
if [ $RET -eq 127 ]
|
||||||
then
|
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 ]
|
elif [ $RET -ne 0 ]
|
||||||
then
|
then
|
||||||
echo ":test-result: FAIL possible segfault: (unit/$RET) ../$FILE:$i"
|
echo ":test-result: FAIL possible segfault: (unit/$RET) ../$FILE"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -195,6 +195,10 @@ int main(int argc, char **argv) {
|
|||||||
std::cout << t->print() << std::endl;
|
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) {
|
if (!test.m_automake_output) {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
@ -202,13 +206,7 @@ int main(int argc, char **argv) {
|
|||||||
if (results.size() == 0) {
|
if (results.size() == 0) {
|
||||||
std::cout << KGRN << "All tests passed" << RESET << std::endl;
|
std::cout << KGRN << "All tests passed" << RESET << std::endl;
|
||||||
} else {
|
} else {
|
||||||
int skp = 0;
|
std::cout << KRED << failed << " failed.";
|
||||||
for (const auto &i : results) {
|
|
||||||
if (i->skipped == true) {
|
|
||||||
skp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << KRED << results.size()-skp << " failed.";
|
|
||||||
std::cout << RESET << std::endl;
|
std::cout << RESET << std::endl;
|
||||||
if (skp > 0) {
|
if (skp > 0) {
|
||||||
std::cout << " " << std::to_string(skp) << " ";
|
std::cout << " " << std::to_string(skp) << " ";
|
||||||
@ -217,13 +215,12 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::pair<std::string, std::vector<UnitTest *> *> a : test) {
|
for (auto a : test) {
|
||||||
std::vector<UnitTest *> *vec = a.second;
|
auto *vec = a.second;
|
||||||
for (int i = 0; i < vec->size(); i++) {
|
for(auto *t : *vec)
|
||||||
delete vec->at(i);
|
delete t;
|
||||||
}
|
|
||||||
delete vec;
|
delete vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#ifndef WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
28
vcbuild.bat
Normal file
28
vcbuild.bat
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user