mirror of
https://github.com/bunkerity/bunkerized-nginx
synced 2023-12-13 21:30:18 +01:00
Merge pull request #537 from bunkerity/dev
Merge branch "dev" into branch "staging"
This commit is contained in:
commit
2eb73d15a1
8
.github/workflows/beta.yml
vendored
8
.github/workflows/beta.yml
vendored
|
@ -7,7 +7,6 @@ on:
|
|||
branches: [beta]
|
||||
|
||||
jobs:
|
||||
|
||||
# Build amd64 + 386 containers images
|
||||
build-containers:
|
||||
strategy:
|
||||
|
@ -133,6 +132,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Get VERSION
|
||||
id: getversion
|
||||
run: echo "version=$(cat src/VERSION | tr -d '\n')" >> "$GITHUB_OUTPUT"
|
||||
|
@ -145,7 +146,8 @@ jobs:
|
|||
needs: [create-arm, wait-builds]
|
||||
strategy:
|
||||
matrix:
|
||||
image: [bunkerweb, bunkerweb-scheduler, bunkerweb-autoconf, bunkerweb-ui]
|
||||
image:
|
||||
[bunkerweb, bunkerweb-scheduler, bunkerweb-autoconf, bunkerweb-ui]
|
||||
include:
|
||||
- release: beta
|
||||
- image: bunkerweb
|
||||
|
@ -281,5 +283,3 @@ jobs:
|
|||
SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY }}
|
||||
SCW_DEFAULT_PROJECT_ID: ${{ secrets.SCW_DEFAULT_PROJECT_ID }}
|
||||
SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_DEFAULT_ORGANIZATION_ID }}
|
||||
|
||||
|
||||
|
|
2
.github/workflows/container-build.yml
vendored
2
.github/workflows/container-build.yml
vendored
|
@ -50,6 +50,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Setup SSH for ARM node
|
||||
if: inputs.CACHE_SUFFIX == 'arm'
|
||||
run: |
|
||||
|
|
3
.github/workflows/create-arm.yml
vendored
3
.github/workflows/create-arm.yml
vendored
|
@ -35,6 +35,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Create ARM VM
|
||||
id: scw
|
||||
uses: scaleway/action-scw@bbcfd65cd2af73456ce439088e0d42c1657c4c38
|
||||
|
@ -72,4 +74,3 @@ jobs:
|
|||
run: ssh root@$SSH_IP "curl -fsSL https://test.docker.com -o test-docker.sh ; sh test-docker.sh"
|
||||
env:
|
||||
SSH_IP: ${{ fromJson(steps.scw.outputs.json).public_ip.address }}
|
||||
|
||||
|
|
1
.github/workflows/dev-update-mmdb.yml
vendored
1
.github/workflows/dev-update-mmdb.yml
vendored
|
@ -17,6 +17,7 @@ jobs:
|
|||
fetch-depth: 0
|
||||
token: ${{ secrets.BUNKERBOT_TOKEN }}
|
||||
ref: dev
|
||||
submodules: recursive
|
||||
- name: Download mmdb files
|
||||
run: |
|
||||
mkdir -p src/bw/misc/
|
||||
|
|
7
.github/workflows/dev.yml
vendored
7
.github/workflows/dev.yml
vendored
|
@ -7,7 +7,6 @@ on:
|
|||
branches: [dev]
|
||||
|
||||
jobs:
|
||||
|
||||
# Containers
|
||||
build-containers:
|
||||
strategy:
|
||||
|
@ -48,6 +47,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
|
@ -75,6 +76,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/core/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
@ -93,4 +96,4 @@ jobs:
|
|||
RELEASE: dev
|
||||
secrets:
|
||||
PRIVATE_REGISTRY: ${{ secrets.PRIVATE_REGISTRY }}
|
||||
PRIVATE_REGISTRY_TOKEN: ${{ secrets.PRIVATE_REGISTRY_TOKEN }}
|
||||
PRIVATE_REGISTRY_TOKEN: ${{ secrets.PRIVATE_REGISTRY_TOKEN }}
|
||||
|
|
5
.github/workflows/doc-to-pdf.yml
vendored
5
.github/workflows/doc-to-pdf.yml
vendored
|
@ -14,10 +14,12 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: "3.10"
|
||||
- name: Install doc requirements
|
||||
run: pip install -r docs/requirements.txt
|
||||
- name: Install chromium
|
||||
|
@ -36,4 +38,3 @@ jobs:
|
|||
with:
|
||||
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
path: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
|
||||
|
|
8
.github/workflows/linux-build.yml
vendored
8
.github/workflows/linux-build.yml
vendored
|
@ -42,20 +42,22 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Extract arch
|
||||
run : |
|
||||
run: |
|
||||
echo "ARCH=${{ env.PLATFORMS }}" | sed 's/linux//g' | sed 's@/@@g' >> "$GITHUB_ENV"
|
||||
env:
|
||||
PLATFORMS: ${{ inputs.PLATFORMS }}
|
||||
- name: Extract linux arch
|
||||
if: inputs.PACKAGE == 'rpm'
|
||||
run : |
|
||||
run: |
|
||||
echo "LARCH=${{ env.ARCH }}" | sed 's/amd64/x86_64/g' | sed 's/arm64/aarch64/g' >> "$GITHUB_ENV"
|
||||
env:
|
||||
ARCH: ${{ env.ARCH }}
|
||||
- name: Extract linux arch
|
||||
if: inputs.PACKAGE == 'deb'
|
||||
run : |
|
||||
run: |
|
||||
echo "LARCH=${{ env.ARCH }}" >> "$GITHUB_ENV"
|
||||
env:
|
||||
ARCH: ${{ env.ARCH }}
|
||||
|
|
3
.github/workflows/push-doc.yml
vendored
3
.github/workflows/push-doc.yml
vendored
|
@ -22,13 +22,14 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.BUNKERBOT_TOKEN }}
|
||||
submodules: recursive
|
||||
- name: Setup git user
|
||||
run: |
|
||||
git config --global user.name "BunkerBot"
|
||||
git config --global user.email "bunkerbot@bunkerity.com"
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: "3.10"
|
||||
- name: Install doc requirements
|
||||
run: pip install -r docs/requirements.txt
|
||||
- name: Push doc
|
||||
|
|
2
.github/workflows/push-docker.yml
vendored
2
.github/workflows/push-docker.yml
vendored
|
@ -31,6 +31,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
|
|
3
.github/workflows/push-github.yml
vendored
3
.github/workflows/push-github.yml
vendored
|
@ -16,6 +16,8 @@ jobs:
|
|||
steps:
|
||||
# Checkout
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
# Get PDF doc
|
||||
- name: Get documentation
|
||||
uses: actions/download-artifact@v3
|
||||
|
@ -60,4 +62,3 @@ jobs:
|
|||
tag_name: v${{ inputs.VERSION }}
|
||||
discussion_category_name: Announcements
|
||||
files: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
|
||||
|
|
2
.github/workflows/push-packagecloud.yml
vendored
2
.github/workflows/push-packagecloud.yml
vendored
|
@ -41,6 +41,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
|
|
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
|
@ -7,7 +7,6 @@ on:
|
|||
branches: [master]
|
||||
|
||||
jobs:
|
||||
|
||||
# Build amd64 + 386 containers images
|
||||
build-containers:
|
||||
strategy:
|
||||
|
@ -133,6 +132,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Get VERSION
|
||||
id: getversion
|
||||
run: echo "version=$(cat src/VERSION | tr -d '\n')" >> "$GITHUB_OUTPUT"
|
||||
|
@ -145,7 +146,8 @@ jobs:
|
|||
needs: [create-arm, wait-builds]
|
||||
strategy:
|
||||
matrix:
|
||||
image: [bunkerweb, bunkerweb-scheduler, bunkerweb-autoconf, bunkerweb-ui]
|
||||
image:
|
||||
[bunkerweb, bunkerweb-scheduler, bunkerweb-autoconf, bunkerweb-ui]
|
||||
include:
|
||||
- release: latest
|
||||
- image: bunkerweb
|
||||
|
@ -280,4 +282,4 @@ jobs:
|
|||
SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY }}
|
||||
SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY }}
|
||||
SCW_DEFAULT_PROJECT_ID: ${{ secrets.SCW_DEFAULT_PROJECT_ID }}
|
||||
SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_DEFAULT_ORGANIZATION_ID }}
|
||||
SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_DEFAULT_ORGANIZATION_ID }}
|
||||
|
|
4
.github/workflows/rm-arm.yml
vendored
4
.github/workflows/rm-arm.yml
vendored
|
@ -22,6 +22,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Delete ARM VM
|
||||
uses: scaleway/action-scw@bbcfd65cd2af73456ce439088e0d42c1657c4c38
|
||||
with:
|
||||
|
@ -30,4 +32,4 @@ jobs:
|
|||
access-key: ${{ secrets.SCW_ACCESS_KEY }}
|
||||
secret-key: ${{ secrets.SCW_SECRET_KEY }}
|
||||
default-project-id: ${{ secrets.SCW_DEFAULT_PROJECT_ID }}
|
||||
default-organization-id: ${{ secrets.SCW_DEFAULT_ORGANIZATION_ID }}
|
||||
default-organization-id: ${{ secrets.SCW_DEFAULT_ORGANIZATION_ID }}
|
||||
|
|
2
.github/workflows/staging-create-infra.yml
vendored
2
.github/workflows/staging-create-infra.yml
vendored
|
@ -20,6 +20,8 @@ jobs:
|
|||
if: inputs.TYPE != 'k8s'
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install terraform
|
||||
uses: hashicorp/setup-terraform@v2
|
||||
- name: Install kubectl
|
||||
|
|
2
.github/workflows/staging-delete-infra.yml
vendored
2
.github/workflows/staging-delete-infra.yml
vendored
|
@ -18,6 +18,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install terraform
|
||||
uses: hashicorp/setup-terraform@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
|
|
2
.github/workflows/staging-tests.yml
vendored
2
.github/workflows/staging-tests.yml
vendored
|
@ -26,6 +26,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Login to private repository
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
|
|
7
.github/workflows/staging.yml
vendored
7
.github/workflows/staging.yml
vendored
|
@ -7,7 +7,6 @@ on:
|
|||
branches: [staging]
|
||||
|
||||
jobs:
|
||||
|
||||
# Build Docker images
|
||||
build-containers:
|
||||
strategy:
|
||||
|
@ -77,6 +76,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
|
@ -135,6 +136,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/core/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
@ -166,4 +169,4 @@ jobs:
|
|||
with:
|
||||
TYPE: ${{ matrix.type }}
|
||||
secrets:
|
||||
CICD_SECRETS: ${{ secrets.CICD_SECRETS }}
|
||||
CICD_SECRETS: ${{ secrets.CICD_SECRETS }}
|
||||
|
|
4
.github/workflows/test-core.yml
vendored
4
.github/workflows/test-core.yml
vendored
|
@ -21,6 +21,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Login to private repository
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
|
@ -37,4 +39,4 @@ jobs:
|
|||
cd ./tests/core/${{ inputs.TEST }}
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i "s@bunkerity/bunkerweb:.*@bunkerweb-tests@" {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i "s@bunkerity/bunkerweb-scheduler:.*@scheduler-tests@" {} \;
|
||||
./test.sh
|
||||
./test.sh
|
||||
|
|
2
.github/workflows/tests-ui.yml
vendored
2
.github/workflows/tests-ui.yml
vendored
|
@ -18,6 +18,8 @@ jobs:
|
|||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Login to private repository
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
|
|
147
.gitmodules
vendored
Normal file
147
.gitmodules
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
[submodule "LuaJIT"]
|
||||
path = src/deps/src/luajit2
|
||||
url = https://github.com/openresty/luajit2.git
|
||||
|
||||
[submodule "zlib"]
|
||||
path = src/deps/src/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
|
||||
[submodule "lua-nginx-module"]
|
||||
path = src/deps/src/lua-nginx-module
|
||||
url = https://github.com/openresty/lua-nginx-module.git
|
||||
|
||||
[submodule "lua-resty-core"]
|
||||
path = src/deps/src/lua-resty-core
|
||||
url = https://github.com/openresty/lua-resty-core.git
|
||||
|
||||
[submodule "ModSecurity"]
|
||||
path = src/deps/src/ModSecurity
|
||||
url = https://github.com/SpiderLabs/ModSecurity.git
|
||||
|
||||
[submodule "libinjection"]
|
||||
path = src/deps/src/libinjection
|
||||
url = https://github.com/libinjection/libinjection.git
|
||||
|
||||
[submodule "ModSecurity-nginx"]
|
||||
path = src/deps/src/ModSecurity-nginx
|
||||
url = https://github.com/SpiderLabs/ModSecurity-nginx.git
|
||||
|
||||
[submodule "lua-resty-lrucache"]
|
||||
path = src/deps/src/lua-resty-lrucache
|
||||
url = https://github.com/openresty/lua-resty-lrucache.git
|
||||
|
||||
[submodule "lua-resty-dns"]
|
||||
path = src/deps/src/lua-resty-dns
|
||||
url = https://github.com/openresty/lua-resty-dns.git
|
||||
|
||||
[submodule "lua-resty-string"]
|
||||
path = src/deps/src/lua-resty-string
|
||||
url = https://github.com/openresty/lua-resty-string.git
|
||||
|
||||
[submodule "lua-cjson"]
|
||||
path = src/deps/src/lua-cjson
|
||||
url = https://github.com/openresty/lua-cjson.git
|
||||
|
||||
[submodule "lua-resty-session"]
|
||||
path = src/deps/src/lua-resty-session
|
||||
url = https://github.com/bungle/lua-resty-session.git
|
||||
|
||||
[submodule "lua-resty-random"]
|
||||
path = src/deps/src/lua-resty-random
|
||||
url = https://github.com/bungle/lua-resty-random.git
|
||||
|
||||
[submodule "lua-gd"]
|
||||
path = src/deps/src/lua-gd
|
||||
url = https://github.com/ittner/lua-gd.git
|
||||
|
||||
[submodule "lua-resty-http"]
|
||||
path = src/deps/src/lua-resty-http
|
||||
url = https://github.com/ledgetech/lua-resty-http.git
|
||||
|
||||
[submodule "lualogging"]
|
||||
path = src/deps/src/lualogging
|
||||
url = https://github.com/lunarmodules/lualogging.git
|
||||
|
||||
[submodule "luasocket"]
|
||||
path = src/deps/src/luasocket
|
||||
url = https://github.com/diegonehab/luasocket.git
|
||||
|
||||
[submodule "luasec"]
|
||||
path = src/deps/src/luasec
|
||||
url = https://github.com/brunoos/luasec.git
|
||||
|
||||
[submodule "lua-resty-ipmatcher"]
|
||||
path = src/deps/src/lua-resty-ipmatcher
|
||||
url = https://github.com/api7/lua-resty-ipmatcher.git
|
||||
|
||||
[submodule "lua-resty-redis"]
|
||||
path = src/deps/src/lua-resty-redis
|
||||
url = https://github.com/openresty/lua-resty-redis.git
|
||||
|
||||
[submodule "lua-resty-upload"]
|
||||
path = src/deps/src/lua-resty-upload
|
||||
url = https://github.com/openresty/lua-resty-upload.git
|
||||
|
||||
[submodule "luajit-geoip"]
|
||||
path = src/deps/src/luajit-geoip
|
||||
url = https://github.com/leafo/luajit-geoip.git
|
||||
|
||||
[submodule "lbase64"]
|
||||
path = src/deps/src/lbase64
|
||||
url = https://github.com/iskolbin/lbase64.git
|
||||
|
||||
[submodule "lua-resty-env"]
|
||||
path = src/deps/src/lua-resty-env
|
||||
url = https://github.com/3scale/lua-resty-env.git
|
||||
|
||||
[submodule "lua-resty-mlcache"]
|
||||
path = src/deps/src/lua-resty-mlcache
|
||||
url = https://github.com/thibaultcha/lua-resty-mlcache.git
|
||||
|
||||
[submodule "lua-resty-template"]
|
||||
path = src/deps/src/lua-resty-template
|
||||
url = https://github.com/bungle/lua-resty-template.git
|
||||
|
||||
[submodule "lua-resty-lock"]
|
||||
path = src/deps/src/lua-resty-lock
|
||||
url = https://github.com/openresty/lua-resty-lock.git
|
||||
|
||||
[submodule "lua-pack"]
|
||||
path = src/deps/src/lua-pack
|
||||
url = https://github.com/kong/lua-pack.git
|
||||
|
||||
[submodule "lua-resty-openssl"]
|
||||
path = src/deps/src/lua-resty-openssl
|
||||
url = https://github.com/fffonion/lua-resty-openssl.git
|
||||
|
||||
[submodule "lua-ffi-zlib"]
|
||||
path = src/deps/src/lua-ffi-zlib
|
||||
url = https://github.com/hamishforbes/lua-ffi-zlib.git
|
||||
|
||||
[submodule "lua-resty-signal"]
|
||||
path = src/deps/src/lua-resty-signal
|
||||
url = https://github.com/openresty/lua-resty-signal.git
|
||||
|
||||
[submodule "libmaxminddb"]
|
||||
path = src/deps/src/libmaxminddb
|
||||
url = https://github.com/maxmind/libmaxminddb.git
|
||||
|
||||
[submodule "headers-more-nginx-module"]
|
||||
path = src/deps/src/headers-more-nginx-module
|
||||
url = https://github.com/openresty/headers-more-nginx-module.git
|
||||
|
||||
[submodule "nginx_cookie_flag_module"]
|
||||
path = src/deps/src/nginx_cookie_flag_module
|
||||
url = https://github.com/AirisX/nginx_cookie_flag_module.git
|
||||
|
||||
[submodule "ngx_brotli"]
|
||||
path = src/deps/src/ngx_brotli
|
||||
url = https://github.com/google/ngx_brotli.git
|
||||
|
||||
[submodule "ngx_devel_kit"]
|
||||
path = src/deps/src/ngx_devel_kit
|
||||
url = https://github.com/vision5/ngx_devel_kit.git
|
||||
|
||||
[submodule "stream-lua-nginx-module"]
|
||||
path = src/deps/src/stream-lua-nginx-module
|
||||
url = https://github.com/openresty/stream-lua-nginx-module.git
|
|
@ -19,7 +19,8 @@ RUN export MAKEFLAGS="-j$(nproc)" && \
|
|||
pip install --no-cache-dir --require-hashes --target /usr/share/bunkerweb/deps/python -r /usr/share/bunkerweb/deps/requirements.txt
|
||||
|
||||
# Remove build dependencies
|
||||
RUN apk del .build-deps
|
||||
RUN apk del .build-deps && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# Copy files
|
||||
# can't exclude specific files/dir from . so we are copying everything by hand
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
FROM nginx:1.24.0-alpine AS builder
|
||||
|
||||
# Install temporary requirements for the dependencies
|
||||
RUN apk add --no-cache --virtual .build-deps bash autoconf libtool automake geoip-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers musl-dev gd-dev gnupg brotli-dev openssl-dev patch readline-dev
|
||||
|
||||
# Copy dependencies sources folder
|
||||
COPY src/deps /tmp/bunkerweb/deps
|
||||
|
||||
# Compile and install dependencies
|
||||
RUN apk add --no-cache --virtual .build-deps bash autoconf libtool automake geoip-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers musl-dev gd-dev gnupg brotli-dev openssl-dev patch readline-dev && \
|
||||
mkdir -p /usr/share/bunkerweb/deps && \
|
||||
RUN mkdir -p /usr/share/bunkerweb/deps && \
|
||||
chmod +x /tmp/bunkerweb/deps/install.sh && \
|
||||
bash /tmp/bunkerweb/deps/install.sh && \
|
||||
apk del .build-deps
|
||||
bash /tmp/bunkerweb/deps/install.sh
|
||||
|
||||
# Clean up temporary dependencies
|
||||
RUN apk del .build-deps && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# Copy python requirements
|
||||
COPY src/common/gen/requirements.txt /usr/share/bunkerweb/deps/requirements.txt
|
||||
|
@ -20,7 +25,8 @@ RUN apk add --no-cache --virtual .build-deps py3-pip && \
|
|||
mkdir -p /usr/share/bunkerweb/deps/python && \
|
||||
export MAKEFLAGS="-j$(nproc)" && \
|
||||
pip install --no-cache-dir --require-hashes --target /usr/share/bunkerweb/deps/python -r /usr/share/bunkerweb/deps/requirements.txt && \
|
||||
apk del .build-deps
|
||||
apk del .build-deps && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# Copy files
|
||||
# can't exclude deps from . so we are copying everything by hand
|
||||
|
|
|
@ -64,7 +64,7 @@ function git_secure_clone() {
|
|||
commit="$2"
|
||||
folder="$(echo "$repo" | sed -E "s@https://github.com/.*/(.*)\.git@\1@")"
|
||||
if [ ! -d "deps/src/${folder}" ] ; then
|
||||
output="$(git clone "$repo" "deps/src/${folder}" 2>&1)"
|
||||
output="$(git clone "$repo" "deps/src/${folder}")"
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "❌ Error cloning $1"
|
||||
echo "$output"
|
||||
|
@ -147,206 +147,3 @@ if [ -f "deps/src/lua-${LUA_VERSION}.tar.gz" ] ; then
|
|||
do_and_check_cmd patch deps/src/lua-${LUA_VERSION}/Makefile deps/misc/lua.patch1
|
||||
do_and_check_cmd patch deps/src/lua-${LUA_VERSION}/src/Makefile deps/misc/lua.patch2
|
||||
fi
|
||||
|
||||
# LuaJIT v2.1-20230410
|
||||
echo "ℹ️ Downloading LuaJIT"
|
||||
git_secure_clone "https://github.com/openresty/luajit2.git" "04f33ff01da97905a1641985fb5c840d234f97f1"
|
||||
|
||||
# lua-nginx-module v0.10.24
|
||||
echo "ℹ️ Downloading lua-nginx-module"
|
||||
git_secure_clone "https://github.com/openresty/lua-nginx-module.git" "68acad14e4a8f42e31d4a4bb5ed44d6f5b55fc1c"
|
||||
|
||||
# lua-resty-core v0.1.26
|
||||
echo "ℹ️ Downloading lua-resty-core"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-core.git" "407000a9856d3a5aab34e8c73f6ab0f049f8b8d7"
|
||||
|
||||
# lua-resty-lrucache v0.13
|
||||
echo "ℹ️ Downloading lua-resty-lrucache"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-lrucache.git" "a79615ec9dc547fdb4aaee59ef8f5a50648ce9fd"
|
||||
|
||||
# lua-resty-dns v0.22
|
||||
echo "ℹ️ Downloading lua-resty-dns"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-dns.git" "869d2fbb009b6ada93a5a10cb93acd1cc12bd53f"
|
||||
|
||||
# lua-resty-session v4.0.3
|
||||
echo "ℹ️ Downloading lua-resty-session"
|
||||
git_secure_clone "https://github.com/bungle/lua-resty-session.git" "3373d8138930b6d1e255bb80d9127503019301d7"
|
||||
|
||||
# lua-resty-random v?
|
||||
echo "ℹ️ Downloading lua-resty-random"
|
||||
git_secure_clone "https://github.com/bungle/lua-resty-random.git" "17b604f7f7dd217557ca548fc1a9a0d373386480"
|
||||
|
||||
# lua-resty-string v0.15
|
||||
echo "ℹ️ Downloading lua-resty-string"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-string.git" "b192878f6ed31b0af237935bbc5a8110a3c2256c"
|
||||
|
||||
# lua-cjson v2.1.0.12
|
||||
echo "ℹ️ Downloading lua-cjson"
|
||||
git_secure_clone "https://github.com/openresty/lua-cjson.git" "881accc8fadca5ec02aa34d364df2a1aa25cd2f9"
|
||||
|
||||
# lua-gd v2.0.33r3+
|
||||
echo "ℹ️ Downloading lua-gd"
|
||||
git_secure_clone "https://github.com/ittner/lua-gd.git" "2ce8e478a8591afd71e607506bc8c64b161bbd30"
|
||||
|
||||
# lua-resty-http v0.17.1
|
||||
echo "ℹ️ Downloading lua-resty-http"
|
||||
git_secure_clone "https://github.com/ledgetech/lua-resty-http.git" "4ab4269cf442ba52507aa2c718f606054452fcad"
|
||||
|
||||
# lualogging v1.8.2
|
||||
echo "ℹ️ Downloading lualogging"
|
||||
git_secure_clone "https://github.com/lunarmodules/lualogging.git" "465c994788f1bc18fca950934fa5ec9a909f496c"
|
||||
|
||||
# luasocket v3.1.0
|
||||
echo "ℹ️ Downloading luasocket"
|
||||
git_secure_clone "https://github.com/diegonehab/luasocket.git" "95b7efa9da506ef968c1347edf3fc56370f0deed"
|
||||
|
||||
# luasec v1.3.1
|
||||
echo "ℹ️ Downloading luasec"
|
||||
git_secure_clone "https://github.com/brunoos/luasec.git" "fddde111f7fe9ad5417d75ebbd70429d13eaad97"
|
||||
|
||||
# lua-resty-ipmatcher v0.6.1 (3 commits after just in case)
|
||||
echo "ℹ️ Downloading lua-resty-ipmatcher"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/lua-resty-ipmatcher" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/api7/lua-resty-ipmatcher.git" "7fbb618f7221b1af1451027d3c64e51f3182761c"
|
||||
if [ "$dopatch" = "yes" ] ; then
|
||||
do_and_check_cmd patch deps/src/lua-resty-ipmatcher/resty/ipmatcher.lua deps/misc/ipmatcher.patch
|
||||
fi
|
||||
|
||||
# lua-resty-redis v0.30
|
||||
echo "ℹ️ Downloading lua-resty-redis"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-redis.git" "d7c25f1b339d79196ff67f061c547a73a920b580"
|
||||
|
||||
# lua-resty-upload v0.11
|
||||
echo "ℹ️ Downloading lua-resty-upload"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-upload.git" "03704aee42f7135e7782688d8a9af63a16015edc"
|
||||
|
||||
# luajit-geoip v2.1.0
|
||||
echo "ℹ️ Downloading luajit-geoip"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/luajit-geoip" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/leafo/luajit-geoip.git" "12a9388207f40c37ad5cf6de2f8e0cc72bf13477"
|
||||
if [ "$dopatch" = "yes" ] ; then
|
||||
do_and_check_cmd patch deps/src/luajit-geoip/geoip/mmdb.lua deps/misc/mmdb.patch
|
||||
fi
|
||||
|
||||
# lbase64 v1.5.3
|
||||
echo "ℹ️ Downloading lbase64"
|
||||
git_secure_clone "https://github.com/iskolbin/lbase64.git" "c261320edbdf82c16409d893a96c28c704aa0ab8"
|
||||
|
||||
# lua-resty-env v0.4.0
|
||||
echo "ℹ️ Downloading lua-resty-env"
|
||||
git_secure_clone "https://github.com/3scale/lua-resty-env.git" "adb294def823dd910ffa11972d2c61eab7cfce3e"
|
||||
|
||||
# lua-resty-mlcache v2.6.0
|
||||
echo "ℹ️ Downloading lua-resty-mlcache"
|
||||
git_secure_clone "https://github.com/thibaultcha/lua-resty-mlcache.git" "f140f56663cbdb9cdd247d29f75c299c702ff6b4"
|
||||
|
||||
# lua-resty-template v2.0
|
||||
echo "ℹ️ Downloading lua-resty-template"
|
||||
git_secure_clone "https://github.com/bungle/lua-resty-template.git" "c08c6bc9e27710806990f2dec0f03b19406976ac"
|
||||
|
||||
# lua-resty-lock v0.09
|
||||
echo "ℹ️ Downloading lua-resty-lock"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-lock.git" "9dc550e56b6f3b1a2f1a31bb270a91813b5b6861"
|
||||
|
||||
# lua-pack v2.0.0
|
||||
echo "ℹ️ Downloading lua-pack"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/lua-pack" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/Kong/lua-pack.git" "495bf30606b9744140258df349862981e3ee7820"
|
||||
if [ "$dopatch" = "yes" ] ; then
|
||||
do_and_check_cmd cp deps/misc/lua-pack.Makefile deps/src/lua-pack/Makefile
|
||||
fi
|
||||
|
||||
# lua-resty-openssl v0.8.22
|
||||
echo "ℹ️ Downloading lua-resty-openssl"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/lua-resty-openssl" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/fffonion/lua-resty-openssl.git" "484907935e60273d31626ac849b23a2d218173de"
|
||||
if [ "$dopatch" == "yes" ] ; then
|
||||
do_and_check_cmd rm -r deps/src/lua-resty-openssl/t
|
||||
fi
|
||||
|
||||
# lua-ffi-zlib v0.5.0
|
||||
echo "ℹ️ Downloading lua-ffi-zlib"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/lua-ffi-zlib" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/hamishforbes/lua-ffi-zlib.git" "1fb69ca505444097c82d2b72e87904f3ed923ae9"
|
||||
if [ "$dopatch" = "yes" ] ; then
|
||||
do_and_check_cmd patch deps/src/lua-ffi-zlib/lib/ffi-zlib.lua deps/misc/lua-ffi-zlib.patch
|
||||
fi
|
||||
|
||||
# lua-resty-signal v0.03
|
||||
echo "ℹ️ Downloading lua-resty-signal"
|
||||
git_secure_clone "https://github.com/openresty/lua-resty-signal.git" "d07163e8cfa673900e66048cd2a1f18523aecf16"
|
||||
|
||||
# ModSecurity v3.0.9
|
||||
echo "ℹ️ Downloading ModSecurity"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/ModSecurity" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/SpiderLabs/ModSecurity.git" "205dac0e8c675182f96b5c2fb06be7d1cf7af2b2"
|
||||
if [ "$dopatch" = "yes" ] ; then
|
||||
do_and_check_cmd patch deps/src/ModSecurity/configure.ac deps/misc/modsecurity.patch
|
||||
fi
|
||||
|
||||
# libinjection v3.10.0+
|
||||
# TODO: check if the latest commit is fine
|
||||
echo "ℹ️ Downloading libinjection"
|
||||
git_secure_clone "https://github.com/libinjection/libinjection.git" "49904c42a6e68dc8f16c022c693e897e4010a06c"
|
||||
do_and_check_cmd cp -r deps/src/libinjection deps/src/ModSecurity/others
|
||||
|
||||
# ModSecurity-nginx v1.0.3
|
||||
echo "ℹ️ Downloading ModSecurity-nginx"
|
||||
dopatch="no"
|
||||
if [ ! -d "deps/src/ModSecurity-nginx" ] ; then
|
||||
dopatch="yes"
|
||||
fi
|
||||
git_secure_clone "https://github.com/SpiderLabs/ModSecurity-nginx.git" "d59e4ad121df702751940fd66bcc0b3ecb51a079"
|
||||
if [ "$dopatch" = "yes" ] ; then
|
||||
do_and_check_cmd patch deps/src/ModSecurity-nginx/src/ngx_http_modsecurity_log.c deps/misc/modsecurity-nginx.patch
|
||||
do_and_check_cmd patch deps/src/ModSecurity-nginx/config deps/misc/config.patch
|
||||
do_and_check_cmd patch deps/src/ModSecurity-nginx/src/ngx_http_modsecurity_common.h deps/misc/ngx_http_modsecurity_common.h.patch
|
||||
do_and_check_cmd patch deps/src/ModSecurity-nginx/src/ngx_http_modsecurity_module.c deps/misc/ngx_http_modsecurity_module.c.patch
|
||||
do_and_check_cmd cp deps/misc/ngx_http_modsecurity_access.c deps/src/ModSecurity-nginx/src
|
||||
fi
|
||||
|
||||
# libmaxminddb v1.7.1
|
||||
echo "ℹ️ Downloading libmaxminddb"
|
||||
git_secure_clone "https://github.com/maxmind/libmaxminddb.git" "ac4d0d2480032a8664e251588e57d7b306ca630c"
|
||||
|
||||
# zlib v1.2.13
|
||||
echo "ℹ️ Downloading zlib"
|
||||
git_secure_clone "https://github.com/madler/zlib.git" "04f42ceca40f73e2978b50e93806c2a18c1281fc"
|
||||
|
||||
# headers-more-nginx-module v0.34
|
||||
echo "ℹ️ Downloading headers-more-nginx-module"
|
||||
git_secure_clone "https://github.com/openresty/headers-more-nginx-module.git" "bea1be3bbf6af28f6aa8cf0c01c07ee1637e2bd0"
|
||||
|
||||
# nginx_cookie_flag_module v1.1.0
|
||||
echo "ℹ️ Downloading nginx_cookie_flag_module"
|
||||
git_secure_clone "https://github.com/AirisX/nginx_cookie_flag_module.git" "4e48acf132952bbed43b28a8e6af0584dacb7b4c"
|
||||
|
||||
# ngx_brotli v1.0.0
|
||||
echo "ℹ️ Downloading ngx_brotli"
|
||||
git_secure_clone "https://github.com/google/ngx_brotli.git" "6e975bcb015f62e1f303054897783355e2a877dc"
|
||||
|
||||
# ngx_devel_kit v0.3.2
|
||||
echo "ℹ️ Downloading ngx_devel_kit"
|
||||
git_secure_clone "https://github.com/vision5/ngx_devel_kit.git" "b4642d6ca01011bd8cd30b253f5c3872b384fd21"
|
||||
|
||||
# stream-lua-nginx-module v0.0.13
|
||||
echo "ℹ️ Downloading stream-lua-nginx-module"
|
||||
git_secure_clone "https://github.com/openresty/stream-lua-nginx-module.git" "309198abf26266f1a3e53c71388ed7bb9d1e5ea2"
|
|
@ -18,9 +18,10 @@ function do_and_check_cmd() {
|
|||
NTASK=$(nproc)
|
||||
|
||||
# Compiling and installing lua
|
||||
echo "ℹ️ Compiling and installing lua-5.1.5"
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-5.1.5" do_and_check_cmd make -j $NTASK linux
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-5.1.5" do_and_check_cmd make INSTALL_TOP=/usr/share/bunkerweb/deps install
|
||||
LUA_VERSION="5.1.5"
|
||||
echo "ℹ️ Compiling and installing lua-${LUA_VERSION}"
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-${LUA_VERSION}" do_and_check_cmd make -j $NTASK linux
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-${LUA_VERSION}" do_and_check_cmd make INSTALL_TOP=/usr/share/bunkerweb/deps install
|
||||
|
||||
# Compiling and installing libmaxminddb
|
||||
echo "ℹ️ Compiling and installing libmaxminddb"
|
||||
|
@ -39,8 +40,8 @@ CHANGE_DIR="/tmp/bunkerweb/deps/src/zlib" do_and_check_cmd make install
|
|||
|
||||
# Compiling and installing ModSecurity
|
||||
echo "ℹ️ Compiling and installing ModSecurity"
|
||||
# temp fix : Debian run it twice
|
||||
# TODO : patch it in clone.sh
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/ModSecurity/configure.ac /tmp/bunkerweb/deps/misc/modsecurity.patch
|
||||
do_and_check_cmd cp -r /tmp/bunkerweb/deps/src/libinjection /tmp/bunkerweb/deps/src/ModSecurity/others
|
||||
cd /tmp/bunkerweb/deps/src/ModSecurity && ./build.sh > /dev/null 2>&1
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/ModSecurity" do_and_check_cmd sh build.sh
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/ModSecurity" do_and_check_cmd ./configure --disable-dependency-tracking --disable-static --disable-examples --disable-doxygen-doc --disable-doxygen-html --disable-valgrind-memcheck --disable-valgrind-helgrind --prefix=/usr/share/bunkerweb/deps --with-maxmind=/usr/share/bunkerweb/deps
|
||||
|
@ -107,6 +108,7 @@ CHANGE_DIR="/tmp/bunkerweb/deps/src/luasec" do_and_check_cmd make LUACPATH=/usr/
|
|||
|
||||
# Installing lua-resty-ipmatcher
|
||||
echo "ℹ️ Installing lua-resty-ipmatcher"
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/lua-resty-ipmatcher/resty/ipmatcher.lua /tmp/bunkerweb/deps/misc/ipmatcher.patch
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-resty-ipmatcher" do_and_check_cmd make INST_PREFIX=/usr/share/bunkerweb/deps INST_LIBDIR=/usr/share/bunkerweb/deps/lib/lua INST_LUADIR=/usr/share/bunkerweb/deps/lib/lua install
|
||||
|
||||
# Installing lua-resty-redis
|
||||
|
@ -119,6 +121,7 @@ CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-resty-upload" do_and_check_cmd make PREF
|
|||
|
||||
# Installing lujit-geoip
|
||||
echo "ℹ️ Installing luajit-geoip"
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/luajit-geoip/geoip/mmdb.lua /tmp/bunkerweb/deps/misc/mmdb.patch
|
||||
do_and_check_cmd cp -r /tmp/bunkerweb/deps/src/luajit-geoip/geoip /usr/share/bunkerweb/deps/lib/lua
|
||||
|
||||
# Installing lbase64
|
||||
|
@ -143,15 +146,18 @@ CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-resty-lock" do_and_check_cmd make PREFIX
|
|||
|
||||
# Installing lua-pack
|
||||
echo "ℹ️ Installing lua-pack"
|
||||
do_and_check_cmd cp /tmp/bunkerweb/deps/misc/lua-pack.Makefile /tmp/bunkerweb/deps/src/lua-pack/Makefile
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-pack" do_and_check_cmd make INST_LIBDIR=/usr/share/bunkerweb/deps/lib/lua LUA_LIBDIR=-L/usr/share/bunkerweb/deps/lib LUA_INCDIR=-I/usr/share/bunkerweb/deps/include install
|
||||
|
||||
# Installing lua-resty-openssl
|
||||
echo "ℹ️ Installing lua-resty-openssl"
|
||||
do_and_check_cmd rm -r /tmp/bunkerweb/deps/src/lua-resty-openssl/t
|
||||
CHANGE_DIR="/tmp/bunkerweb/deps/src/lua-resty-openssl" do_and_check_cmd make LUA_LIB_DIR=/usr/share/bunkerweb/deps/lib/lua install
|
||||
do_and_check_cmd cp /tmp/bunkerweb/deps/src/lua-resty-openssl/lib/resty/openssl.lua /usr/share/bunkerweb/deps/lib/lua/resty
|
||||
|
||||
# Installing lua-ffi-zlib
|
||||
echo "ℹ️ Installing lua-ffi-zlib"
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/lua-ffi-zlib/lib/ffi-zlib.lua /tmp/bunkerweb/deps/misc/lua-ffi-zlib.patch
|
||||
do_and_check_cmd cp /tmp/bunkerweb/deps/src/lua-ffi-zlib/lib/ffi-zlib.lua /usr/share/bunkerweb/deps/lib/lua
|
||||
|
||||
# Installing lua-resty-signal
|
||||
|
@ -168,6 +174,13 @@ CONFARGS="$(echo -n "$CONFARGS" | sed "s/--with-ld-opt='-Wl/--with-ld-opt='-lpcr
|
|||
if [ "$OS" = "fedora" ] ; then
|
||||
CONFARGS="$(echo -n "$CONFARGS" | sed "s/--with-ld-opt='.*'/--with-ld-opt=-lpcre/" | sed "s/--with-cc-opt='.*'//")"
|
||||
fi
|
||||
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/ModSecurity-nginx/src/ngx_http_modsecurity_log.c /tmp/bunkerweb/deps/misc/modsecurity-nginx.patch
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/ModSecurity-nginx/config /tmp/bunkerweb/deps/misc/config.patch
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/ModSecurity-nginx/src/ngx_http_modsecurity_common.h /tmp/bunkerweb/deps/misc/ngx_http_modsecurity_common.h.patch
|
||||
do_and_check_cmd patch /tmp/bunkerweb/deps/src/ModSecurity-nginx/src/ngx_http_modsecurity_module.c /tmp/bunkerweb/deps/misc/ngx_http_modsecurity_module.c.patch
|
||||
do_and_check_cmd cp /tmp/bunkerweb/deps/misc/ngx_http_modsecurity_access.c /tmp/bunkerweb/deps/src/ModSecurity-nginx/src
|
||||
|
||||
echo '#!/bin/bash' > "/tmp/bunkerweb/deps/src/nginx-${NGINX_VERSION}/configure-fix.sh"
|
||||
echo "./configure $CONFARGS --add-dynamic-module=/tmp/bunkerweb/deps/src/headers-more-nginx-module --add-dynamic-module=/tmp/bunkerweb/deps/src/nginx_cookie_flag_module --add-dynamic-module=/tmp/bunkerweb/deps/src/lua-nginx-module --add-dynamic-module=/tmp/bunkerweb/deps/src/ngx_brotli --add-dynamic-module=/tmp/bunkerweb/deps/src/ngx_devel_kit --add-dynamic-module=/tmp/bunkerweb/deps/src/stream-lua-nginx-module" --add-dynamic-module=/tmp/bunkerweb/deps/src/ModSecurity-nginx >> "/tmp/bunkerweb/deps/src/nginx-${NGINX_VERSION}/configure-fix.sh"
|
||||
do_and_check_cmd chmod +x "/tmp/bunkerweb/deps/src/nginx-${NGINX_VERSION}/configure-fix.sh"
|
||||
|
|
1
src/deps/src/ModSecurity
Submodule
1
src/deps/src/ModSecurity
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 205dac0e8c675182f96b5c2fb06be7d1cf7af2b2
|
1
src/deps/src/ModSecurity-nginx
Submodule
1
src/deps/src/ModSecurity-nginx
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit d59e4ad121df702751940fd66bcc0b3ecb51a079
|
|
@ -1,19 +0,0 @@
|
|||
#name: "Close stale issues"
|
||||
#on:
|
||||
# schedule:
|
||||
# - cron: "0 0 * * *"
|
||||
#
|
||||
#jobs:
|
||||
# stale:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/stale@v3
|
||||
# with:
|
||||
# repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
|
||||
# stale-pr-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
|
||||
# stale-issue-label: 'no-issue-activity'
|
||||
# stale-pr-label: 'no-pr-activity'
|
||||
# exempt-issue-label: 'nostale,work-in-progress'
|
||||
# days-before-stale: 30
|
||||
# days-before-close: 5
|
|
@ -1,47 +0,0 @@
|
|||
sudo: required
|
||||
dist: bionic
|
||||
|
||||
os: linux
|
||||
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libyajl-dev
|
||||
- libgeoip-dev
|
||||
- liblmdb-dev
|
||||
|
||||
env:
|
||||
- VER_NGINX=1.21.0
|
||||
- VER_NGINX=1.20.1
|
||||
|
||||
before_script:
|
||||
- cd ..
|
||||
- git clone https://github.com/SpiderLabs/ModSecurity.git
|
||||
- cd ModSecurity
|
||||
- git checkout v3/master
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
- ./build.sh
|
||||
- ./configure --without-lmdb
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ..
|
||||
- wget http://nginx.org/download/nginx-${VER_NGINX}.tar.gz && tar -xf nginx-${VER_NGINX}.tar.gz
|
||||
- cd nginx-${VER_NGINX}
|
||||
- ./configure --with-http_auth_request_module --with-http_v2_module --add-module=../ModSecurity-nginx
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ..
|
||||
- wget http://hg.nginx.org/nginx-tests/archive/tip.tar.gz
|
||||
- tar xvzf tip.tar.gz
|
||||
- cd nginx-tests-*
|
||||
- cp ../ModSecurity-nginx/tests/* .
|
||||
- export TEST_NGINX_BINARY=/usr/local/nginx/sbin/nginx
|
||||
|
||||
script:
|
||||
- prove .
|
|
@ -1,2 +0,0 @@
|
|||
zimmerle = Felipe Zimmerle <felipe@zimmerle.org>
|
||||
defanator = Andrei Belov <defanator@gmail.com>
|
|
@ -1,70 +0,0 @@
|
|||
v1.0.3 - 2022-May-24
|
||||
--------------------
|
||||
|
||||
- Support http protocol versions besides 0.9, 1.0, 1.1, 2.0
|
||||
[Issue #224 - @HQuest, @martinhsv]
|
||||
- Support for building with nginx configured with PCRE2
|
||||
[Issue #260 - @defanator]
|
||||
|
||||
v1.0.2 - 2021-Jun-02
|
||||
--------------------
|
||||
|
||||
- Fix auditlog in case of internal redirect
|
||||
[Issue #90 - @AirisX, @defanator]
|
||||
- Fix nginx sends response without headers
|
||||
[Issue #238 - @airween, @defanator]
|
||||
- Fix nginx not clearing body cache (caused by incomplete fix for #187)
|
||||
[Issue #216 - @krewi1, @martinhsv]
|
||||
- Fix config setting not respected: client_body_in_file_only on
|
||||
[Issue #187 - @martinhsv]
|
||||
- Fix audit_log not generated for disruptive actions
|
||||
[Issue #170, #2220, #2237 - @victorhora]
|
||||
- Exit more gracefully if uri length is zero
|
||||
[@martinhsv]
|
||||
|
||||
v1.0.1 - 2019-Dec-16
|
||||
--------------------
|
||||
|
||||
- Fixed obtaining of server_addr
|
||||
[Issue #167, #168 - @defanator]
|
||||
- Avoid processing of subrequests initiated by the error_page
|
||||
[Issue #76, #164, #165 - @defanator]
|
||||
- Tests: extend request body tests
|
||||
[Issue #142,#143 - @defanator]
|
||||
- Added basic tests over HTTP/2
|
||||
[Issue #145 - @defanator]
|
||||
- Module configuration refactoring
|
||||
[Issue #139 - @defanator]
|
||||
- Restore r->write_event_handler after reading request body
|
||||
[Issue #131 - @defanator]
|
||||
- Increase log level for disruptive actions to "error"
|
||||
[Issue #112 - @victorhora]
|
||||
- Support for generating transaction ID in nginx
|
||||
[Issue #126 - @defanator]
|
||||
- Extend request body tests with ARGS_POST case
|
||||
[Issue #124 - @defanator]
|
||||
- Fix tests after 42a472a change in library
|
||||
[Issue #122 - @defanator]
|
||||
- Fix processing of response body when gzip compression is enabled
|
||||
[Issue #107 - @turchanov]
|
||||
- Fixed processing of response body chunks in
|
||||
ngx_http_modsecurity_body_filter.
|
||||
[Issue #105 - @turchanov, @defanator]
|
||||
- Fix incorrect handling of request/response body data chain of ngx_buf_t
|
||||
buffers
|
||||
[Issue #104 - @turchanov, @defanator]
|
||||
- Pool pointer is now handled in ngx_http_modsecurity_config_cleanup
|
||||
[Issue #87 - @AirisX, @defanator, @zimmerle]
|
||||
- Fix memory leak in intervention processing
|
||||
[Issue #100 - @defanator]
|
||||
- Emit connector version in error log
|
||||
[Issue #88 - @defanator]
|
||||
- Fixed memory leak on config cleanup.
|
||||
[Issue #80 - @AirisX, @defanator]
|
||||
|
||||
|
||||
v1.0.0 - 2017-Dec-20
|
||||
--------------------
|
||||
|
||||
- First version of ModSecurity-nginx connector
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,266 +0,0 @@
|
|||
|
||||
<img src="https://github.com/SpiderLabs/ModSecurity/raw/v3/master/others/modsec.png" width="50%">
|
||||
|
||||
[![Build Status](https://travis-ci.org/SpiderLabs/ModSecurity-nginx.svg?branch=master)](https://travis-ci.org/SpiderLabs/ModSecurity-nginx)
|
||||
[![](https://raw.githubusercontent.com/ZenHubIO/support/master/zenhub-badge.png)](https://zenhub.com)
|
||||
|
||||
|
||||
The ModSecurity-nginx connector is the connection point between nginx and libmodsecurity (ModSecurity v3). Said another way, this project provides a communication channel between nginx and libmodsecurity. This connector is required to use LibModSecurity with nginx.
|
||||
|
||||
The ModSecurity-nginx connector takes the form of an nginx module. The module simply serves as a layer of communication between nginx and ModSecurity.
|
||||
|
||||
Notice that this project depends on libmodsecurity rather than ModSecurity (version 2.9 or less).
|
||||
|
||||
### What is the difference between this project and the old ModSecurity add-on for nginx?
|
||||
|
||||
The old version uses ModSecurity standalone, which is a wrapper for
|
||||
Apache internals to link ModSecurity to nginx. This current version is closer
|
||||
to nginx, consuming the new libmodsecurity which is no longer dependent on
|
||||
Apache. As a result, this current version has less dependencies, fewer bugs, and is faster. In addition, some new functionality is also provided - such as the possibility of use of global rules configuration with per directory/location customizations (e.g. SecRuleRemoveById).
|
||||
|
||||
|
||||
# Compilation
|
||||
|
||||
Before compile this software make sure that you have libmodsecurity installed.
|
||||
You can download it from the [ModSecurity git repository](https://github.com/SpiderLabs/ModSecurity). For information pertaining to the compilation and installation of libmodsecurity please consult the documentation provided along with it.
|
||||
|
||||
With libmodsecurity installed, you can proceed with the installation of the ModSecurity-nginx connector, which follows the nginx third-party module installation procedure. From the nginx source directory:
|
||||
|
||||
```
|
||||
./configure --add-module=/path/to/ModSecurity-nginx
|
||||
```
|
||||
|
||||
Or, to build a dynamic module:
|
||||
|
||||
```
|
||||
./configure --add-dynamic-module=/path/to/ModSecurity-nginx --with-compat
|
||||
```
|
||||
|
||||
Note that when building a dynamic module, your nginx source version
|
||||
needs to match the version of nginx you're compiling this for.
|
||||
|
||||
Further information about nginx third-party add-ons support are available here:
|
||||
http://wiki.nginx.org/3rdPartyModules
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
ModSecurity for nginx extends your nginx configuration directives.
|
||||
It adds four new directives and they are:
|
||||
|
||||
modsecurity
|
||||
-----------
|
||||
**syntax:** *modsecurity on | off*
|
||||
|
||||
**context:** *http, server, location*
|
||||
|
||||
**default:** *off*
|
||||
|
||||
Turns on or off ModSecurity functionality.
|
||||
Note that this configuration directive is no longer related to the SecRule state.
|
||||
Instead, it now serves solely as an nginx flag to enable or disable the module.
|
||||
|
||||
modsecurity_rules_file
|
||||
----------------------
|
||||
**syntax:** *modsecurity_rules_file <path to rules file>*
|
||||
|
||||
**context:** *http, server, location*
|
||||
|
||||
**default:** *no*
|
||||
|
||||
Specifies the location of the modsecurity configuration file, e.g.:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
modsecurity on;
|
||||
location / {
|
||||
root /var/www/html;
|
||||
modsecurity_rules_file /etc/my_modsecurity_rules.conf;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
modsecurity_rules_remote
|
||||
------------------------
|
||||
**syntax:** *modsecurity_rules_remote <key> <URL to rules>*
|
||||
|
||||
**context:** *http, server, location*
|
||||
|
||||
**default:** *no*
|
||||
|
||||
Specifies from where (on the internet) a modsecurity configuration file will be downloaded.
|
||||
It also specifies the key that will be used to authenticate to that server:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
modsecurity on;
|
||||
location / {
|
||||
root /var/www/html;
|
||||
modsecurity_rules_remote my-server-key https://my-own-server/rules/download;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
modsecurity_rules
|
||||
-----------------
|
||||
**syntax:** *modsecurity_rules <modsecurity rule>*
|
||||
|
||||
**context:** *http, server, location*
|
||||
|
||||
**default:** *no*
|
||||
|
||||
Allows for the direct inclusion of a ModSecurity rule into the nginx configuration.
|
||||
The following example is loading rules from a file and injecting specific configurations per directory/alias:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
modsecurity on;
|
||||
location / {
|
||||
root /var/www/html;
|
||||
modsecurity_rules_file /etc/my_modsecurity_rules.conf;
|
||||
}
|
||||
location /ops {
|
||||
root /var/www/html/opts;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDebugLog /tmp/modsec_debug.log
|
||||
SecDebugLogLevel 9
|
||||
SecRuleRemoveById 10
|
||||
';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
modsecurity_transaction_id
|
||||
--------------------------
|
||||
**syntax:** *modsecurity_transaction_id string*
|
||||
|
||||
**context:** *http, server, location*
|
||||
|
||||
**default:** *no*
|
||||
|
||||
Allows to pass transaction ID from nginx instead of generating it in the library.
|
||||
This can be useful for tracing purposes, e.g. consider this configuration:
|
||||
|
||||
```nginx
|
||||
log_format extended '$remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" $request_id';
|
||||
|
||||
server {
|
||||
server_name host1;
|
||||
modsecurity on;
|
||||
modsecurity_transaction_id "host1-$request_id";
|
||||
access_log logs/host1-access.log extended;
|
||||
error_log logs/host1-error.log;
|
||||
location / {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
server_name host2;
|
||||
modsecurity on;
|
||||
modsecurity_transaction_id "host2-$request_id";
|
||||
access_log logs/host2-access.log extended;
|
||||
error_log logs/host2-error.log;
|
||||
location / {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using a combination of log_format and modsecurity_transaction_id you will
|
||||
be able to find correlations between access log and error log entries
|
||||
using the same unique identificator.
|
||||
|
||||
String can contain variables.
|
||||
|
||||
|
||||
# Contributing
|
||||
|
||||
As an open source project we invite (and encourage) anyone from the community to contribute to our project. This may take the form of: new
|
||||
functionality, bug fixes, bug reports, beginners user support, and anything else that you
|
||||
are willing to help with. Thank you.
|
||||
|
||||
|
||||
## Providing Patches
|
||||
|
||||
We prefer to have your patch within the GitHub infrastructure to facilitate our
|
||||
review work, and our QA integration. GitHub provides an excellent
|
||||
documentation on how to perform “Pull Requests”. More information available
|
||||
here: https://help.github.com/articles/using-pull-requests/
|
||||
|
||||
Please respect the coding style in use. Pull requests can include various commits, so
|
||||
provide one fix or one functionality per commit. Do not change anything outside
|
||||
the scope of your target work (e.g. coding style in a function that you have
|
||||
passed by).
|
||||
|
||||
### Don’t know where to start?
|
||||
|
||||
Within our code there are various items marked as TODO or FIXME that may need
|
||||
your attention. Check the list of items by performing a grep:
|
||||
|
||||
```
|
||||
$ cd /path/to/modsecurity-nginx
|
||||
$ egrep -Rin "TODO|FIXME" -R *
|
||||
```
|
||||
|
||||
You may also take a look at recent bug reports and open issues to get an idea of what kind of help we are looking for.
|
||||
|
||||
### Testing your patch
|
||||
|
||||
Along with the manual testing, we strongly recommend that you to use the nginx test
|
||||
utility to make sure that you patch does not adversely affect the behavior or performance of nginx.
|
||||
|
||||
The nginx tests are available on: http://hg.nginx.org/nginx-tests/
|
||||
|
||||
To use those tests, make sure you have the Perl utility prove (part of Perl 5)
|
||||
and proceed with the following commands:
|
||||
|
||||
```
|
||||
$ cp /path/to/ModSecurity-nginx/tests/* /path/to/nginx/test/repository
|
||||
$ cd /path/to/nginx/test/repository
|
||||
$ TEST_NGINX_BINARY=/path/to/your/nginx prove .
|
||||
```
|
||||
|
||||
If you are facing problems getting your added functionality to pass all the nginx tests, feel free to contact us or the nginx mailing list at: http://nginx.org/en/support.html
|
||||
|
||||
### Debugging
|
||||
|
||||
We respect the nginx debugging schema. By using the configuration option
|
||||
"--with-debug" during the nginx configuration you will also be enabling the
|
||||
connector's debug messages. Core dumps and crashes are expected to be debugged
|
||||
in the same fashion that is used to debug nginx. For further information,
|
||||
please check the nginx debugging information: http://wiki.nginx.org/Debugging
|
||||
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
If you are facing a configuration issue or if something is not working as you
|
||||
expect it to be, please use ModSecurity user’s mailing list. Issues on GitHub
|
||||
are also welcome, but we prefer to have users question on the mailing list first,
|
||||
where you can reach an entire community. Also don’t forget to look for an
|
||||
existing issue before opening a new one.
|
||||
|
||||
Lastly, If you are planning to open an issue on GitHub, please don’t forget to tell us the
|
||||
version of your libmodsecurity and the version of the nginx connector you are running.
|
||||
|
||||
### Security issue
|
||||
|
||||
Please do not publicly report any security issue. Instead, contact us at:
|
||||
security@modsecurity.org to report the issue. Once the problem is fixed we will provide you with credit for the discovery.
|
||||
|
||||
|
||||
## Feature Request
|
||||
|
||||
We would love to discuss any ideas that you may have for a new feature. Please keep in mind this is a community driven project so be sure to contact the community via the mailing list to get feedback first. Alternatively,
|
||||
feel free to open GitHub issues requesting for new features. Before opening a new issue, please check if there is an existing feature request for the desired functionality.
|
||||
|
||||
|
||||
## Packaging
|
||||
|
||||
Having our packages in distros on time is something we highly desire. Let us know if
|
||||
there is anything we can do to facilitate your work as a packager.
|
||||
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
# vim: filetype=sh
|
||||
|
||||
# If $NGX_IGNORE_RPATH is set to "YES", we will ignore explicit
|
||||
# library path specification on resulting binary, allowing libmodsecurity.so
|
||||
# to be relocated across configured library pathes (adjust /etc/ld.so.conf
|
||||
# or set $LD_LIBRARY_PATH environment variable to manage them)
|
||||
#
|
||||
# $YAJL_LIB variable may need to be populated in case of non-standard
|
||||
# path of libyajl.so's installation
|
||||
|
||||
ngx_feature_name=
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <modsecurity/modsecurity.h>"
|
||||
ngx_feature_libs="-lmodsecurity"
|
||||
ngx_feature_test='printf("hello");'
|
||||
ngx_modsecurity_opt_I=
|
||||
ngx_modsecurity_opt_L=
|
||||
|
||||
YAJL_EXTRA=
|
||||
if test -n "$YAJL_LIB"; then
|
||||
YAJL_EXTRA="-L$YAJL_LIB -lyajl"
|
||||
fi
|
||||
|
||||
# If $MODSECURITY_INC is specified, lets use it. Otherwise lets try
|
||||
# the default paths
|
||||
#
|
||||
if [ -n "$MODSECURITY_INC" -o -n "$MODSECURITY_LIB" ]; then
|
||||
# explicitly set ModSecurity lib path
|
||||
ngx_feature="ModSecurity library in \"$MODSECURITY_LIB\" and \"$MODSECURITY_INC\" (specified by the MODSECURITY_LIB and MODSECURITY_INC env)"
|
||||
ngx_feature_path="$MODSECURITY_INC"
|
||||
ngx_modsecurity_opt_I="-I$MODSECURITY_INC"
|
||||
ngx_modsecurity_opt_L="-L$MODSECURITY_LIB $YAJL_EXTRA"
|
||||
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R$MODSECURITY_LIB -L$MODSECURITY_LIB -lmodsecurity $YAJL_EXTRA"
|
||||
elif [ "$NGX_IGNORE_RPATH" != "YES" -a $NGX_SYSTEM = "Linux" ]; then
|
||||
ngx_feature_libs="-Wl,-rpath,$MODSECURITY_LIB -L$MODSECURITY_LIB -lmodsecurity $YAJL_EXTRA"
|
||||
else
|
||||
ngx_feature_libs="-L$MODSECURITY_LIB -lmodsecurity $YAJL_EXTRA"
|
||||
fi
|
||||
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
cat << END
|
||||
$0: error: ngx_http_modsecurity_module requires the ModSecurity library and MODSECURITY_LIB is defined as "$MODSECURITY_LIB" and MODSECURITY_INC (path for modsecurity.h) "$MODSECURITY_INC", but we cannot find ModSecurity there.
|
||||
END
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# auto-discovery
|
||||
ngx_feature="ModSecurity library"
|
||||
ngx_feature_libs="-lmodsecurity"
|
||||
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
ngx_feature="ModSecurity library in /usr/local/modsecurity"
|
||||
ngx_feature_path="/usr/local/modsecurity/include"
|
||||
if [ $NGX_RPATH = YES ]; then
|
||||
ngx_feature_libs="-R/usr/local/modsecurity/lib -L/usr/local/modsecurity/lib -lmodsecurity"
|
||||
elif [ "$NGX_IGNORE_RPATH" != "YES" -a $NGX_SYSTEM = "Linux" ]; then
|
||||
ngx_feature_libs="-Wl,-rpath,/usr/local/modsecurity/lib -L/usr/local/modsecurity/lib -lmodsecurity"
|
||||
else
|
||||
ngx_feature_libs="-L/usr/local/modsecurity/lib -lmodsecurity"
|
||||
fi
|
||||
|
||||
. auto/feature
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
cat << END
|
||||
$0: error: ngx_http_modsecurity_module requires the ModSecurity library.
|
||||
END
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
ngx_addon_name=ngx_http_modsecurity_module
|
||||
|
||||
# We must place ngx_http_modsecurity_module after ngx_http_gzip_filter_module
|
||||
# in load order list to be able to read response body before it gets compressed
|
||||
# (for filter modules later initialization means earlier execution).
|
||||
#
|
||||
# Nginx implements load ordering only for dynamic modules and only a BEFORE part
|
||||
# of "ngx_module_order". So we list all of the modules that come after
|
||||
# ngx_http_gzip_filter_module as a BEFORE dependency for
|
||||
# ngx_http_modsecurity_module.
|
||||
#
|
||||
# For static compilation HTTP_FILTER_MODULES will be patched later.
|
||||
|
||||
modsecurity_dependency="ngx_http_postpone_filter_module \
|
||||
ngx_http_ssi_filter_module \
|
||||
ngx_http_charset_filter_module \
|
||||
ngx_http_xslt_filter_module \
|
||||
ngx_http_image_filter_module \
|
||||
ngx_http_sub_filter_module \
|
||||
ngx_http_addition_filter_module \
|
||||
ngx_http_gunzip_filter_module \
|
||||
ngx_http_userid_filter_module \
|
||||
ngx_http_headers_filter_module \
|
||||
ngx_http_copy_filter_module"
|
||||
|
||||
|
||||
if test -n "$ngx_module_link"; then
|
||||
ngx_module_type=HTTP_FILTER
|
||||
ngx_module_name="$ngx_addon_name"
|
||||
ngx_module_srcs="$ngx_addon_dir/src/ngx_http_modsecurity_module.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_access.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_header_filter.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_body_filter.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_log.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_rewrite.c \
|
||||
"
|
||||
ngx_module_deps="$ngx_addon_dir/src/ddebug.h \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_common.h \
|
||||
"
|
||||
ngx_module_libs="$ngx_feature_libs"
|
||||
ngx_module_incs="$ngx_feature_path"
|
||||
|
||||
ngx_module_order="ngx_http_chunked_filter_module \
|
||||
ngx_http_v2_filter_module \
|
||||
ngx_http_range_header_filter_module \
|
||||
ngx_http_gzip_filter_module \
|
||||
$ngx_module_name \
|
||||
$modsecurity_dependency";
|
||||
|
||||
. auto/module
|
||||
else
|
||||
CFLAGS="$ngx_modsecurity_opt_I $CFLAGS"
|
||||
NGX_LD_OPT="$ngx_modsecurity_opt_L $NGX_LD_OPT"
|
||||
|
||||
CORE_INCS="$CORE_INCS $ngx_feature_path"
|
||||
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
|
||||
|
||||
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_modsecurity_module"
|
||||
NGX_ADDON_SRCS="\
|
||||
$NGX_ADDON_SRCS \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_module.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_access.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_header_filter.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_body_filter.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_log.c \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_rewrite.c \
|
||||
"
|
||||
|
||||
NGX_ADDON_DEPS="\
|
||||
$NGX_ADDON_DEPS \
|
||||
$ngx_addon_dir/src/ddebug.h \
|
||||
$ngx_addon_dir/src/ngx_http_modsecurity_common.h \
|
||||
"
|
||||
fi
|
||||
|
||||
#
|
||||
# Nginx does not provide reliable way to introduce our module into required
|
||||
# place in static ($ngx_module_link=ADDON) compilation mode, so we must
|
||||
# explicitly update module "ordering rules".
|
||||
#
|
||||
if [ "$ngx_module_link" != DYNAMIC ] ; then
|
||||
# Reposition modsecurity module to satisfy $modsecurity_dependency
|
||||
# (this mimics dependency resolution made by ngx_add_module() function
|
||||
# though less optimal in terms of computational complexity).
|
||||
modules=
|
||||
found=
|
||||
for module in $HTTP_FILTER_MODULES; do
|
||||
# skip our module name from the original list
|
||||
if [ "$module" = "$ngx_addon_name" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -z "${found}" ]; then
|
||||
for item in $modsecurity_dependency; do
|
||||
if [ "$module" = "$item" ]; then
|
||||
modules="${modules} $ngx_addon_name"
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
modules="${modules} $module"
|
||||
done
|
||||
if [ -z "${found}" ]; then
|
||||
# This must never happen since ngx_http_copy_filter_module must be in HTTP_FILTER_MODULES
|
||||
# and we stated dependency on it in $modsecurity_dependency
|
||||
echo "$0: error: cannot reposition modsecurity module in HTTP_FILTER_MODULES list"
|
||||
exit 1
|
||||
fi
|
||||
HTTP_FILTER_MODULES="${modules}"
|
||||
fi
|
|
@ -1,37 +0,0 @@
|
|||
#!/usr/bin/env stap
|
||||
|
||||
global begin_rule
|
||||
global rules
|
||||
global rules_phase
|
||||
|
||||
|
||||
# Rules
|
||||
probe process("/usr/local/lib/libmodsecurity.so.3").function("evaluate@rule.cc*")
|
||||
{
|
||||
begin_rule = gettimeofday_us();
|
||||
}
|
||||
|
||||
probe process("/usr/local/lib/libmodsecurity.so.3").function("evaluate@rule.cc*").return
|
||||
{
|
||||
elapsed_rule = gettimeofday_us() - begin_rule
|
||||
rules[$this->m_ruleId] <<< elapsed_rule
|
||||
rules_phase[$this->m_ruleId] = $this->m_phase
|
||||
}
|
||||
|
||||
|
||||
# Resume
|
||||
probe end
|
||||
{
|
||||
foreach ([rule] in rules)
|
||||
{
|
||||
if (@count(rules[rule])) {
|
||||
p = rules_phase[rule] - 1;
|
||||
if (p <= 0) {
|
||||
p = 1
|
||||
}
|
||||
printf("Phase %d;Rule ID: %d %u\n", p, rule, @avg(rules[rule]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
git clean -xfdi
|
||||
git submodule foreach --recursive git clean -xfdi
|
||||
|
||||
VERSION=`git describe --tags`
|
||||
DIR_NAME="modsecurity-nginx-$VERSION"
|
||||
TAR_NAME="modsecurity-nginx-$VERSION.tar.gz"
|
||||
|
||||
MY_DIR=${PWD##*/}
|
||||
|
||||
cd ..
|
||||
tar --transform "s/^$MY_DIR/$DIR_NAME/" -cvzf $TAR_NAME --exclude .git $MY_DIR
|
||||
|
||||
sha256sum $TAR_NAME > $TAR_NAME.sha256
|
||||
gpg --detach-sign -a $TAR_NAME
|
||||
|
||||
cd -
|
||||
echo $TAR_NAME ": done."
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
|
||||
|
||||
// From: https://raw.githubusercontent.com/openresty/lua-nginx-module/master/src/ddebug.h
|
||||
|
||||
/*
|
||||
* Copyright (C) Yichun Zhang (agentzh)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DDEBUG_H_INCLUDED_
|
||||
#define _DDEBUG_H_INCLUDED_
|
||||
|
||||
#include <ngx_core.h>
|
||||
|
||||
/*
|
||||
* #undef MODSECURITY_DDEBUG
|
||||
* #define MODSECURITY_DDEBUG 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Setting MODSECURITY_SANITY_CHECKS will help you in the debug process. By
|
||||
* defining MODSECURITY_SANITY_CHECKS a set of functions will be executed in
|
||||
* order to make sure the well behavior of ModSecurity, letting you know (via
|
||||
* debug_logs) if something unexpected happens.
|
||||
*
|
||||
* If performance is not a concern, it is safe to keep it set.
|
||||
*
|
||||
*/
|
||||
#ifndef MODSECURITY_SANITY_CHECKS
|
||||
#define MODSECURITY_SANITY_CHECKS 0
|
||||
#endif
|
||||
|
||||
#if defined(MODSECURITY_DDEBUG) && (MODSECURITY_DDEBUG)
|
||||
|
||||
# if (NGX_HAVE_VARIADIC_MACROS)
|
||||
|
||||
# define dd(...) fprintf(stderr, "modsec *** %s: ", __func__); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fprintf(stderr, " at %s line %d.\n", __FILE__, __LINE__)
|
||||
|
||||
# else
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
static void dd(const char *fmt, ...) {
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
# if (NGX_HAVE_VARIADIC_MACROS)
|
||||
|
||||
# define dd(...)
|
||||
|
||||
# else
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
static void dd(const char *fmt, ...) {
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MODSECURITY_DDEBUG) && (MODSECURITY_DDEBUG)
|
||||
|
||||
#define dd_check_read_event_handler(r) \
|
||||
dd("r->read_event_handler = %s", \
|
||||
r->read_event_handler == ngx_http_block_reading ? \
|
||||
"ngx_http_block_reading" : \
|
||||
r->read_event_handler == ngx_http_test_reading ? \
|
||||
"ngx_http_test_reading" : \
|
||||
r->read_event_handler == ngx_http_request_empty_handler ? \
|
||||
"ngx_http_request_empty_handler" : "UNKNOWN")
|
||||
|
||||
#define dd_check_write_event_handler(r) \
|
||||
dd("r->write_event_handler = %s", \
|
||||
r->write_event_handler == ngx_http_handler ? \
|
||||
"ngx_http_handler" : \
|
||||
r->write_event_handler == ngx_http_core_run_phases ? \
|
||||
"ngx_http_core_run_phases" : \
|
||||
r->write_event_handler == ngx_http_request_empty_handler ? \
|
||||
"ngx_http_request_empty_handler" : "UNKNOWN")
|
||||
|
||||
#else
|
||||
|
||||
#define dd_check_read_event_handler(r)
|
||||
#define dd_check_write_event_handler(r)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _DDEBUG_H_INCLUDED_ */
|
||||
|
||||
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
|
||||
void
|
||||
ngx_http_modsecurity_request_read(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
#if defined(nginx_version) && nginx_version >= 8011
|
||||
r->main->count--;
|
||||
#endif
|
||||
|
||||
if (ctx->waiting_more_body)
|
||||
{
|
||||
ctx->waiting_more_body = 0;
|
||||
r->write_event_handler = ngx_http_core_run_phases;
|
||||
ngx_http_core_run_phases(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_access_handler(ngx_http_request_t *r)
|
||||
{
|
||||
#if 1
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
|
||||
dd("catching a new _access_ phase handler");
|
||||
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
if (mcf == NULL || mcf->enable != 1)
|
||||
{
|
||||
dd("ModSecurity not enabled... returning");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
/*
|
||||
* FIXME:
|
||||
* In order to perform some tests, let's accept everything.
|
||||
*
|
||||
if (r->method != NGX_HTTP_GET &&
|
||||
r->method != NGX_HTTP_POST && r->method != NGX_HTTP_HEAD) {
|
||||
dd("ModSecurity is not ready to deal with anything different from " \
|
||||
"POST, GET or HEAD");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
*/
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("recovering ctx: %p", ctx);
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
dd("ctx is null; Nothing we can do, returning an error.");
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->intervention_triggered) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (ctx->waiting_more_body == 1)
|
||||
{
|
||||
dd("waiting for more data before proceed. / count: %d",
|
||||
r->main->count);
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
if (ctx->body_requested == 0)
|
||||
{
|
||||
ngx_int_t rc = NGX_OK;
|
||||
|
||||
ctx->body_requested = 1;
|
||||
|
||||
dd("asking for the request body, if any. Count: %d",
|
||||
r->main->count);
|
||||
/**
|
||||
* TODO: Check if there is any benefit to use request_body_in_single_buf set to 1.
|
||||
*
|
||||
* saw some module using this request_body_in_single_buf
|
||||
* but not sure what exactly it does, same for the others options below.
|
||||
*
|
||||
* r->request_body_in_single_buf = 1;
|
||||
*/
|
||||
r->request_body_in_single_buf = 1;
|
||||
r->request_body_in_persistent_file = 1;
|
||||
if (!r->request_body_in_file_only) {
|
||||
// If the above condition fails, then the flag below will have been
|
||||
// set correctly elsewhere. We need to set the flag here for other
|
||||
// conditions (client_body_in_file_only not used but
|
||||
// client_body_buffer_size is)
|
||||
r->request_body_in_clean_file = 1;
|
||||
}
|
||||
|
||||
rc = ngx_http_read_client_request_body(r,
|
||||
ngx_http_modsecurity_request_read);
|
||||
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
#if (nginx_version < 1002006) || \
|
||||
(nginx_version >= 1003000 && nginx_version < 1003009)
|
||||
r->main->count--;
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
if (rc == NGX_AGAIN)
|
||||
{
|
||||
dd("nginx is asking us to wait for more data.");
|
||||
|
||||
ctx->waiting_more_body = 1;
|
||||
return NGX_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->waiting_more_body == 0)
|
||||
{
|
||||
int ret = 0;
|
||||
int already_inspected = 0;
|
||||
|
||||
dd("request body is ready to be processed");
|
||||
|
||||
r->write_event_handler = ngx_http_core_run_phases;
|
||||
|
||||
ngx_chain_t *chain = r->request_body->bufs;
|
||||
|
||||
/**
|
||||
* TODO: Speed up the analysis by sending chunk while they arrive.
|
||||
*
|
||||
* Notice that we are waiting for the full request body to
|
||||
* start to process it, it may not be necessary. We may send
|
||||
* the chunks to ModSecurity while nginx keep calling this
|
||||
* function.
|
||||
*/
|
||||
|
||||
if (r->request_body->temp_file != NULL) {
|
||||
ngx_str_t file_path = r->request_body->temp_file->file.name;
|
||||
const char *file_name = ngx_str_to_char(file_path, r->pool);
|
||||
if (file_name == (char*)-1) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
/*
|
||||
* Request body was saved to a file, probably we don't have a
|
||||
* copy of it in memory.
|
||||
*/
|
||||
dd("request body inspection: file -- %s", file_name);
|
||||
|
||||
msc_request_body_from_file(ctx->modsec_transaction, file_name);
|
||||
|
||||
already_inspected = 1;
|
||||
} else {
|
||||
dd("inspection request body in memory.");
|
||||
}
|
||||
|
||||
while (chain && !already_inspected)
|
||||
{
|
||||
u_char *data = chain->buf->pos;
|
||||
|
||||
msc_append_request_body(ctx->modsec_transaction, data,
|
||||
chain->buf->last - data);
|
||||
|
||||
if (chain->buf->last_buf) {
|
||||
break;
|
||||
}
|
||||
chain = chain->next;
|
||||
|
||||
/* XXX: chains are processed one-by-one, maybe worth to pass all chains and then call intervention() ? */
|
||||
|
||||
/**
|
||||
* ModSecurity may perform stream inspection on this buffer,
|
||||
* it may ask for a intervention in consequence of that.
|
||||
*
|
||||
*/
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* At this point, all the request body was sent to ModSecurity
|
||||
* and we want to make sure that all the request body inspection
|
||||
* happened; consequently we have to check if ModSecurity have
|
||||
* returned any kind of intervention.
|
||||
*/
|
||||
|
||||
/* XXX: once more -- is body can be modified ? content-length need to be adjusted ? */
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_request_body(ctx->modsec_transaction);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (r->error_page) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dd("Nothing to add on the body inspection, reclaiming a NGX_DECLINED");
|
||||
#endif
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
|
||||
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
|
||||
|
||||
/* XXX: check behaviour on few body filters installed */
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_body_filter_init(void)
|
||||
{
|
||||
ngx_http_next_body_filter = ngx_http_top_body_filter;
|
||||
ngx_http_top_body_filter = ngx_http_modsecurity_body_filter;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
ngx_chain_t *chain = in;
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
ngx_list_part_t *part = &r->headers_out.headers.part;
|
||||
ngx_table_elt_t *data = part->elts;
|
||||
ngx_uint_t i = 0;
|
||||
#endif
|
||||
|
||||
if (in == NULL) {
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("body filter, recovering ctx: %p", ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
if (ctx->intervention_triggered) {
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
if (mcf != NULL && mcf->sanity_checks_enabled != NGX_CONF_UNSET)
|
||||
{
|
||||
#if 0
|
||||
dd("dumping stored ctx headers");
|
||||
for (i = 0; i < ctx->sanity_headers_out->nelts; i++)
|
||||
{
|
||||
ngx_http_modsecurity_header_t *vals = ctx->sanity_headers_out->elts;
|
||||
ngx_str_t *s2 = &vals[i].name, *s3 = &vals[i].value;
|
||||
dd(" dump[%d]: name = '%.*s', value = '%.*s'", (int)i,
|
||||
(int)s2->len, (char*)s2->data,
|
||||
(int)s3->len, (char*)s3->data);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Identify if there is a header that was not inspected by ModSecurity.
|
||||
*/
|
||||
int worth_to_fail = 0;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
int found = 0;
|
||||
ngx_uint_t j = 0;
|
||||
ngx_table_elt_t *s1;
|
||||
ngx_http_modsecurity_header_t *vals;
|
||||
|
||||
if (i >= part->nelts)
|
||||
{
|
||||
if (part->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
part = part->next;
|
||||
data = part->elts;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
vals = ctx->sanity_headers_out->elts;
|
||||
s1 = &data[i];
|
||||
|
||||
/*
|
||||
* Headers that were inspected by ModSecurity.
|
||||
*/
|
||||
while (j < ctx->sanity_headers_out->nelts)
|
||||
{
|
||||
ngx_str_t *s2 = &vals[j].name;
|
||||
ngx_str_t *s3 = &vals[j].value;
|
||||
|
||||
if (s1->key.len == s2->len && ngx_strncmp(s1->key.data, s2->data, s1->key.len) == 0)
|
||||
{
|
||||
if (s1->value.len == s3->len && ngx_strncmp(s1->value.data, s3->data, s1->value.len) == 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (!found) {
|
||||
dd("header: `%.*s' with value: `%.*s' was not inspected by ModSecurity",
|
||||
(int) s1->key.len,
|
||||
(const char *) s1->key.data,
|
||||
(int) s1->value.len,
|
||||
(const char *) s1->value.data);
|
||||
worth_to_fail++;
|
||||
}
|
||||
}
|
||||
|
||||
if (worth_to_fail)
|
||||
{
|
||||
dd("%d header(s) were not inspected by ModSecurity, so exiting", worth_to_fail);
|
||||
return ngx_http_filter_finalize_request(r,
|
||||
&ngx_http_modsecurity_module, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int is_request_processed = 0;
|
||||
for (; chain != NULL; chain = chain->next)
|
||||
{
|
||||
u_char *data = chain->buf->pos;
|
||||
int ret;
|
||||
|
||||
msc_append_response_body(ctx->modsec_transaction, data, chain->buf->last - data);
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (ret > 0) {
|
||||
return ngx_http_filter_finalize_request(r,
|
||||
&ngx_http_modsecurity_module, ret);
|
||||
}
|
||||
|
||||
/* XXX: chain->buf->last_buf || chain->buf->last_in_chain */
|
||||
is_request_processed = chain->buf->last_buf;
|
||||
|
||||
if (is_request_processed) {
|
||||
ngx_pool_t *old_pool;
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_response_body(ctx->modsec_transaction);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
/* XXX: I don't get how body from modsec being transferred to nginx's buffer. If so - after adjusting of nginx's
|
||||
XXX: body we can proceed to adjust body size (content-length). see xslt_body_filter() for example */
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
return ngx_http_filter_finalize_request(r,
|
||||
&ngx_http_modsecurity_module, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_request_processed)
|
||||
{
|
||||
dd("buffer was not fully loaded! ctx: %p", ctx);
|
||||
}
|
||||
|
||||
/* XXX: xflt_filter() -- return NGX_OK here */
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_HTTP_MODSECURITY_COMMON_H_INCLUDED_
|
||||
#define _NGX_HTTP_MODSECURITY_COMMON_H_INCLUDED_
|
||||
|
||||
#include <nginx.h>
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
#include <modsecurity/modsecurity.h>
|
||||
#include <modsecurity/transaction.h>
|
||||
|
||||
|
||||
/* #define MSC_USE_RULES_SET 1 */
|
||||
|
||||
#if defined(MODSECURITY_CHECK_VERSION)
|
||||
#if MODSECURITY_VERSION_NUM >= 304010
|
||||
#define MSC_USE_RULES_SET 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MSC_USE_RULES_SET)
|
||||
#include <modsecurity/rules_set.h>
|
||||
#else
|
||||
#include <modsecurity/rules.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* TAG_NUM:
|
||||
*
|
||||
* Alpha - 001
|
||||
* Beta - 002
|
||||
* Dev - 010
|
||||
* Rc1 - 051
|
||||
* Rc2 - 052
|
||||
* ... - ...
|
||||
* Release- 100
|
||||
*
|
||||
*/
|
||||
|
||||
#define MODSECURITY_NGINX_MAJOR "1"
|
||||
#define MODSECURITY_NGINX_MINOR "0"
|
||||
#define MODSECURITY_NGINX_PATCHLEVEL "3"
|
||||
#define MODSECURITY_NGINX_TAG ""
|
||||
#define MODSECURITY_NGINX_TAG_NUM "100"
|
||||
|
||||
#define MODSECURITY_NGINX_VERSION MODSECURITY_NGINX_MAJOR "." \
|
||||
MODSECURITY_NGINX_MINOR "." MODSECURITY_NGINX_PATCHLEVEL \
|
||||
MODSECURITY_NGINX_TAG
|
||||
|
||||
#define MODSECURITY_NGINX_VERSION_NUM MODSECURITY_NGINX_MAJOR \
|
||||
MODSECURITY_NGINX_MINOR MODSECURITY_NGINX_PATCHLEVEL \
|
||||
MODSECURITY_NGINX_TAG_NUM
|
||||
|
||||
#define MODSECURITY_NGINX_WHOAMI "ModSecurity-nginx v" \
|
||||
MODSECURITY_NGINX_VERSION
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_str_t value;
|
||||
} ngx_http_modsecurity_header_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_request_t *r;
|
||||
Transaction *modsec_transaction;
|
||||
ModSecurityIntervention *delayed_intervention;
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
/*
|
||||
* Should be filled with the headers that were sent to ModSecurity.
|
||||
*
|
||||
* The idea is to compare this set of headers with the headers that were
|
||||
* sent to the client. This check was placed because we don't have control
|
||||
* over other modules, thus, we may partially inspect the headers.
|
||||
*
|
||||
*/
|
||||
ngx_array_t *sanity_headers_out;
|
||||
#endif
|
||||
|
||||
unsigned waiting_more_body:1;
|
||||
unsigned body_requested:1;
|
||||
unsigned processed:1;
|
||||
unsigned logged:1;
|
||||
unsigned intervention_triggered:1;
|
||||
} ngx_http_modsecurity_ctx_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
void *pool;
|
||||
ModSecurity *modsec;
|
||||
ngx_uint_t rules_inline;
|
||||
ngx_uint_t rules_file;
|
||||
ngx_uint_t rules_remote;
|
||||
} ngx_http_modsecurity_main_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
void *pool;
|
||||
/* RulesSet or Rules */
|
||||
void *rules_set;
|
||||
|
||||
ngx_flag_t enable;
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_flag_t sanity_checks_enabled;
|
||||
#endif
|
||||
|
||||
ngx_http_complex_value_t *transaction_id;
|
||||
} ngx_http_modsecurity_conf_t;
|
||||
|
||||
|
||||
typedef ngx_int_t (*ngx_http_modsecurity_resolv_header_pt)(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t offset;
|
||||
ngx_http_modsecurity_resolv_header_pt resolver;
|
||||
} ngx_http_modsecurity_header_out_t;
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_modsecurity_module;
|
||||
|
||||
/* ngx_http_modsecurity_module.c */
|
||||
int ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r, ngx_int_t early_log);
|
||||
ngx_http_modsecurity_ctx_t *ngx_http_modsecurity_create_ctx(ngx_http_request_t *r);
|
||||
char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p);
|
||||
#if (NGX_PCRE2)
|
||||
#define ngx_http_modsecurity_pcre_malloc_init(x) NULL
|
||||
#define ngx_http_modsecurity_pcre_malloc_done(x) (void)x
|
||||
#else
|
||||
ngx_pool_t *ngx_http_modsecurity_pcre_malloc_init(ngx_pool_t *pool);
|
||||
void ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool);
|
||||
#endif
|
||||
|
||||
/* ngx_http_modsecurity_body_filter.c */
|
||||
ngx_int_t ngx_http_modsecurity_body_filter_init(void);
|
||||
ngx_int_t ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in);
|
||||
|
||||
/* ngx_http_modsecurity_header_filter.c */
|
||||
ngx_int_t ngx_http_modsecurity_header_filter_init(void);
|
||||
ngx_int_t ngx_http_modsecurity_header_filter(ngx_http_request_t *r);
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
int ngx_http_modsecurity_store_ctx_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value);
|
||||
#endif
|
||||
|
||||
/* ngx_http_modsecurity_log.c */
|
||||
void ngx_http_modsecurity_log(void *log, const void* data);
|
||||
ngx_int_t ngx_http_modsecurity_log_handler(ngx_http_request_t *r);
|
||||
|
||||
/* ngx_http_modsecurity_access.c */
|
||||
ngx_int_t ngx_http_modsecurity_access_handler(ngx_http_request_t *r);
|
||||
|
||||
/* ngx_http_modsecurity_rewrite.c */
|
||||
ngx_int_t ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r);
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_MODSECURITY_COMMON_H_INCLUDED_ */
|
|
@ -1,558 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
|
||||
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
|
||||
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_server(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_date(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_content_length(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_content_type(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_last_modified(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_connection(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_transfer_encoding(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
static ngx_int_t ngx_http_modsecurity_resolv_header_vary(ngx_http_request_t *r, ngx_str_t name, off_t offset);
|
||||
|
||||
ngx_http_modsecurity_header_out_t ngx_http_modsecurity_headers_out[] = {
|
||||
|
||||
{ ngx_string("Server"),
|
||||
offsetof(ngx_http_headers_out_t, server),
|
||||
ngx_http_modsecurity_resolv_header_server },
|
||||
|
||||
{ ngx_string("Date"),
|
||||
offsetof(ngx_http_headers_out_t, date),
|
||||
ngx_http_modsecurity_resolv_header_date },
|
||||
|
||||
{ ngx_string("Content-Length"),
|
||||
offsetof(ngx_http_headers_out_t, content_length_n),
|
||||
ngx_http_modsecurity_resolv_header_content_length },
|
||||
|
||||
{ ngx_string("Content-Type"),
|
||||
offsetof(ngx_http_headers_out_t, content_type),
|
||||
ngx_http_modsecurity_resolv_header_content_type },
|
||||
|
||||
{ ngx_string("Last-Modified"),
|
||||
offsetof(ngx_http_headers_out_t, last_modified),
|
||||
ngx_http_modsecurity_resolv_header_last_modified },
|
||||
|
||||
{ ngx_string("Connection"),
|
||||
0,
|
||||
ngx_http_modsecurity_resolv_header_connection },
|
||||
|
||||
{ ngx_string("Transfer-Encoding"),
|
||||
0,
|
||||
ngx_http_modsecurity_resolv_header_transfer_encoding },
|
||||
|
||||
{ ngx_string("Vary"),
|
||||
0,
|
||||
ngx_http_modsecurity_resolv_header_vary },
|
||||
|
||||
#if 0
|
||||
{ ngx_string("Content-Encoding"),
|
||||
offsetof(ngx_http_headers_out_t, content_encoding),
|
||||
NGX_TABLE },
|
||||
|
||||
{ ngx_string("Cache-Control"),
|
||||
offsetof(ngx_http_headers_out_t, cache_control),
|
||||
NGX_ARRAY },
|
||||
|
||||
{ ngx_string("Location"),
|
||||
offsetof(ngx_http_headers_out_t, location),
|
||||
NGX_TABLE },
|
||||
|
||||
{ ngx_string("Content-Range"),
|
||||
offsetof(ngx_http_headers_out_t, content_range),
|
||||
NGX_TABLE },
|
||||
|
||||
{ ngx_string("Accept-Ranges"),
|
||||
offsetof(ngx_http_headers_out_t, accept_ranges),
|
||||
NGX_TABLE },
|
||||
|
||||
returiders_out[i].name 1;
|
||||
{ ngx_string("WWW-Authenticate"),
|
||||
offsetof(ngx_http_headers_out_t, www_authenticate),
|
||||
NGX_TABLE },
|
||||
|
||||
{ ngx_string("Expires"),
|
||||
offsetof(ngx_http_headers_out_t, expires),
|
||||
NGX_TABLE },
|
||||
#endif
|
||||
{ ngx_null_string, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
int
|
||||
ngx_http_modsecurity_store_ctx_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
ngx_http_modsecurity_header_t *hdr;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
if (ctx == NULL || ctx->sanity_headers_out == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
if (mcf == NULL || mcf->sanity_checks_enabled == NGX_CONF_UNSET)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
hdr = ngx_array_push(ctx->sanity_headers_out);
|
||||
if (hdr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hdr->name.data = ngx_pnalloc(r->pool, name->len);
|
||||
hdr->value.data = ngx_pnalloc(r->pool, value->len);
|
||||
if (hdr->name.data == NULL || hdr->value.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(hdr->name.data, name->data, name->len);
|
||||
hdr->name.len = name->len;
|
||||
ngx_memcpy(hdr->value.data, value->data, value->len);
|
||||
hdr->value.len = value->len;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_server(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
static char ngx_http_server_full_string[] = NGINX_VER;
|
||||
static char ngx_http_server_string[] = "nginx";
|
||||
|
||||
ngx_http_core_loc_conf_t *clcf = NULL;
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
ngx_str_t value;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
if (clcf->server_tokens) {
|
||||
value.data = (u_char *)ngx_http_server_full_string;
|
||||
value.len = sizeof(ngx_http_server_full_string);
|
||||
} else {
|
||||
value.data = (u_char *)ngx_http_server_string;
|
||||
value.len = sizeof(ngx_http_server_string);
|
||||
}
|
||||
} else {
|
||||
ngx_table_elt_t *h = r->headers_out.server;
|
||||
value.data = h->value.data;
|
||||
value.len = h->value.len;
|
||||
}
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_date(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
ngx_str_t date;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
if (r->headers_out.date == NULL) {
|
||||
date.data = ngx_cached_http_time.data;
|
||||
date.len = ngx_cached_http_time.len;
|
||||
} else {
|
||||
ngx_table_elt_t *h = r->headers_out.date;
|
||||
date.data = h->value.data;
|
||||
date.len = h->value.len;
|
||||
}
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &date);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) date.data,
|
||||
date.len);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_content_length(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
ngx_str_t value;
|
||||
char buf[NGX_INT64_LEN+2];
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
if (r->headers_out.content_length_n > 0)
|
||||
{
|
||||
ngx_sprintf((u_char *)buf, "%O%Z", r->headers_out.content_length_n);
|
||||
value.data = (unsigned char *)buf;
|
||||
value.len = strlen(buf);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
|
||||
#endif
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_content_type(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
if (r->headers_out.content_type.len > 0)
|
||||
{
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &r->headers_out.content_type);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) r->headers_out.content_type.data,
|
||||
r->headers_out.content_type.len);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_last_modified(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
u_char buf[1024], *p;
|
||||
ngx_str_t value;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
if (r->headers_out.last_modified_time == -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = ngx_http_time(buf, r->headers_out.last_modified_time);
|
||||
|
||||
value.data = buf;
|
||||
value.len = (int)(p-buf);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_connection(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
ngx_http_core_loc_conf_t *clcf = NULL;
|
||||
char *connection = NULL;
|
||||
ngx_str_t value;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
|
||||
connection = "upgrade";
|
||||
} else if (r->keepalive) {
|
||||
connection = "keep-alive";
|
||||
if (clcf->keepalive_header)
|
||||
{
|
||||
u_char buf[1024];
|
||||
ngx_sprintf(buf, "timeout=%T%Z", clcf->keepalive_header);
|
||||
ngx_str_t name2 = ngx_string("Keep-Alive");
|
||||
|
||||
value.data = buf;
|
||||
value.len = strlen((char *)buf);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name2, &value);
|
||||
#endif
|
||||
|
||||
msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name2.data,
|
||||
name2.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
} else {
|
||||
connection = "close";
|
||||
}
|
||||
|
||||
value.data = (u_char *) connection;
|
||||
value.len = strlen(connection);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_transfer_encoding(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
|
||||
if (r->chunked) {
|
||||
ngx_str_t value = ngx_string("chunked");
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_resolv_header_vary(ngx_http_request_t *r, ngx_str_t name, off_t offset)
|
||||
{
|
||||
#if (NGX_HTTP_GZIP)
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
ngx_http_core_loc_conf_t *clcf = NULL;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
if (r->gzip_vary && clcf->gzip_vary) {
|
||||
ngx_str_t value = ngx_string("Accept-Encoding");
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
|
||||
#endif
|
||||
|
||||
return msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) name.data,
|
||||
name.len,
|
||||
(const unsigned char *) value.data,
|
||||
value.len);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_header_filter_init(void)
|
||||
{
|
||||
ngx_http_next_header_filter = ngx_http_top_header_filter;
|
||||
ngx_http_top_header_filter = ngx_http_modsecurity_header_filter;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_header_filter(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_list_part_t *part = &r->headers_out.headers.part;
|
||||
ngx_table_elt_t *data = part->elts;
|
||||
ngx_uint_t i = 0;
|
||||
int ret = 0;
|
||||
ngx_uint_t status;
|
||||
char *http_response_ver;
|
||||
ngx_pool_t *old_pool;
|
||||
|
||||
|
||||
/* XXX: if NOT_MODIFIED, do we need to process it at all? see xslt_header_filter() */
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("header filter, recovering ctx: %p", ctx);
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
dd("something really bad happened or ModSecurity is disabled. going to the next filter.");
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (ctx->intervention_triggered) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
/* XXX: can it happen ? already processed i mean */
|
||||
/* XXX: check behaviour on 'ModSecurity off' */
|
||||
|
||||
if (ctx && ctx->processed)
|
||||
{
|
||||
/*
|
||||
* FIXME: verify if this request is already processed.
|
||||
*/
|
||||
dd("Already processed... going to the next header...");
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lets ask nginx to keep the response body in memory
|
||||
*
|
||||
* FIXME: I don't see a reason to keep it `1' when SecResponseBody is disabled.
|
||||
*/
|
||||
r->filter_need_in_memory = 1;
|
||||
|
||||
ctx->processed = 1;
|
||||
/*
|
||||
*
|
||||
* Assuming ModSecurity module is running immediately before the
|
||||
* ngx_http_header_filter, we will be able to populate ModSecurity with
|
||||
* headers from the headers_out structure.
|
||||
*
|
||||
* As ngx_http_header_filter place a direct call to the
|
||||
* ngx_http_write_filter_module, we cannot hook between those two. In order
|
||||
* to enumerate all headers, we first look at the headers_out structure,
|
||||
* and later we look into the ngx_list_part_t. The ngx_list_part_t must be
|
||||
* checked. Other module(s) in the chain may added some content to it.
|
||||
*
|
||||
*/
|
||||
for (i = 0; ngx_http_modsecurity_headers_out[i].name.len; i++)
|
||||
{
|
||||
dd(" Sending header to ModSecurity - header: `%.*s'.",
|
||||
(int) ngx_http_modsecurity_headers_out[i].name.len,
|
||||
ngx_http_modsecurity_headers_out[i].name.data);
|
||||
|
||||
ngx_http_modsecurity_headers_out[i].resolver(r,
|
||||
ngx_http_modsecurity_headers_out[i].name,
|
||||
ngx_http_modsecurity_headers_out[i].offset);
|
||||
}
|
||||
|
||||
for (i = 0 ;; i++)
|
||||
{
|
||||
if (i >= part->nelts)
|
||||
{
|
||||
if (part->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
part = part->next;
|
||||
data = part->elts;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &data[i].key, &data[i].value);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Doing this ugly cast here, explanation on the request_header
|
||||
*/
|
||||
msc_add_n_response_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) data[i].key.data,
|
||||
data[i].key.len,
|
||||
(const unsigned char *) data[i].value.data,
|
||||
data[i].value.len);
|
||||
}
|
||||
|
||||
/* prepare extra paramters for msc_process_response_headers() */
|
||||
if (r->err_status) {
|
||||
status = r->err_status;
|
||||
} else {
|
||||
status = r->headers_out.status;
|
||||
}
|
||||
|
||||
/*
|
||||
* NGINX always sends HTTP response with HTTP/1.1, except cases when
|
||||
* HTTP V2 module is enabled, and request has been posted with HTTP/2.0.
|
||||
*/
|
||||
http_response_ver = "HTTP 1.1";
|
||||
#if (NGX_HTTP_V2)
|
||||
if (r->stream) {
|
||||
http_response_ver = "HTTP 2.0";
|
||||
}
|
||||
#endif
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_response_headers(ctx->modsec_transaction, status, http_response_ver);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (r->error_page) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
if (ret > 0) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity_module, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Proxies will not like this... but it is necessary to unset
|
||||
* the content length in order to manipulate the content of
|
||||
* response body in ModSecurity.
|
||||
*
|
||||
* This header may arrive at the client before ModSecurity had
|
||||
* a change to make any modification. That is why it is necessary
|
||||
* to set this to -1 here.
|
||||
*
|
||||
* We need to have some kind of flag the decide if ModSecurity
|
||||
* will make a modification or not. If not, keep the content and
|
||||
* make the proxy servers happy.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The line below is commented to make the spdy test to work
|
||||
*/
|
||||
//r->headers_out.content_length_n = -1;
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
|
||||
|
||||
void
|
||||
ngx_http_modsecurity_log(void *log, const void* data)
|
||||
{
|
||||
const char *msg;
|
||||
if (log == NULL) {
|
||||
return;
|
||||
}
|
||||
msg = (const char *) data;
|
||||
|
||||
ngx_log_error(NGX_LOG_WARN, (ngx_log_t *)log, 0, "%s", msg);
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_log_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
|
||||
dd("catching a new _log_ phase handler");
|
||||
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
if (mcf == NULL || mcf->enable != 1)
|
||||
{
|
||||
dd("ModSecurity not enabled... returning");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
if (r->method != NGX_HTTP_GET &&
|
||||
r->method != NGX_HTTP_POST && r->method != NGX_HTTP_HEAD) {
|
||||
dd("ModSecurity is not ready to deal with anything different from " \
|
||||
"POST, GET or HEAD");
|
||||
return NGX_OK;
|
||||
}
|
||||
*/
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("recovering ctx: %p", ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
dd("something really bad happened here. returning NGX_ERROR");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->logged) {
|
||||
dd("already logged earlier");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
dd("calling msc_process_logging for %p", ctx);
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_logging(ctx->modsec_transaction);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
|
@ -1,793 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
#include "stdio.h"
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
static ngx_int_t ngx_http_modsecurity_init(ngx_conf_t *cf);
|
||||
static void *ngx_http_modsecurity_create_main_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_modsecurity_init_main_conf(ngx_conf_t *cf, void *conf);
|
||||
static void *ngx_http_modsecurity_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child);
|
||||
static void ngx_http_modsecurity_cleanup_instance(void *data);
|
||||
static void ngx_http_modsecurity_cleanup_rules(void *data);
|
||||
|
||||
|
||||
/*
|
||||
* PCRE malloc/free workaround, based on
|
||||
* https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_pcrefix.c
|
||||
*/
|
||||
|
||||
#if !(NGX_PCRE2)
|
||||
static void *(*old_pcre_malloc)(size_t);
|
||||
static void (*old_pcre_free)(void *ptr);
|
||||
static ngx_pool_t *ngx_http_modsec_pcre_pool = NULL;
|
||||
|
||||
static void *
|
||||
ngx_http_modsec_pcre_malloc(size_t size)
|
||||
{
|
||||
if (ngx_http_modsec_pcre_pool) {
|
||||
return ngx_palloc(ngx_http_modsec_pcre_pool, size);
|
||||
}
|
||||
|
||||
fprintf(stderr, "error: modsec pcre malloc failed due to empty pcre pool");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_http_modsec_pcre_free(void *ptr)
|
||||
{
|
||||
if (ngx_http_modsec_pcre_pool) {
|
||||
ngx_pfree(ngx_http_modsec_pcre_pool, ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* this may happen when called from cleanup handlers */
|
||||
fprintf(stderr, "error: modsec pcre free failed due to empty pcre pool");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_http_modsecurity_pcre_malloc_init(ngx_pool_t *pool)
|
||||
{
|
||||
ngx_pool_t *old_pool;
|
||||
|
||||
if (pcre_malloc != ngx_http_modsec_pcre_malloc) {
|
||||
ngx_http_modsec_pcre_pool = pool;
|
||||
|
||||
old_pcre_malloc = pcre_malloc;
|
||||
old_pcre_free = pcre_free;
|
||||
|
||||
pcre_malloc = ngx_http_modsec_pcre_malloc;
|
||||
pcre_free = ngx_http_modsec_pcre_free;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old_pool = ngx_http_modsec_pcre_pool;
|
||||
ngx_http_modsec_pcre_pool = pool;
|
||||
|
||||
return old_pool;
|
||||
}
|
||||
|
||||
void
|
||||
ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool)
|
||||
{
|
||||
ngx_http_modsec_pcre_pool = old_pool;
|
||||
|
||||
if (old_pool == NULL) {
|
||||
pcre_malloc = old_pcre_malloc;
|
||||
pcre_free = old_pcre_free;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ngx_string's are not null-terminated in common case, so we need to convert
|
||||
* them into null-terminated ones before passing to ModSecurity
|
||||
*/
|
||||
ngx_inline char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p)
|
||||
{
|
||||
char *str = NULL;
|
||||
|
||||
if (a.len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = ngx_pnalloc(p, a.len+1);
|
||||
if (str == NULL) {
|
||||
dd("failed to allocate memory to convert space ngx_string to C string");
|
||||
/* We already returned NULL for an empty string, so return -1 here to indicate allocation error */
|
||||
return (char *)-1;
|
||||
}
|
||||
ngx_memcpy(str, a.data, a.len);
|
||||
str[a.len] = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
ngx_inline int
|
||||
ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r, ngx_int_t early_log)
|
||||
{
|
||||
char *log = NULL;
|
||||
ModSecurityIntervention intervention;
|
||||
intervention.status = 200;
|
||||
intervention.url = NULL;
|
||||
intervention.log = NULL;
|
||||
intervention.disruptive = 0;
|
||||
ngx_http_modsecurity_ctx_t *ctx = NULL;
|
||||
|
||||
dd("processing intervention");
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if (msc_intervention(transaction, &intervention) == 0) {
|
||||
dd("nothing to do");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log = intervention.log;
|
||||
if (intervention.log == NULL) {
|
||||
log = "(no log message was specified)";
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, (ngx_log_t *)r->connection->log, 0, "%s", log);
|
||||
|
||||
if (intervention.log != NULL) {
|
||||
free(intervention.log);
|
||||
}
|
||||
|
||||
if (intervention.url != NULL)
|
||||
{
|
||||
dd("intervention -- redirecting to: %s with status code: %d", intervention.url, intervention.status);
|
||||
|
||||
if (r->header_sent)
|
||||
{
|
||||
dd("Headers are already sent. Cannot perform the redirection at this point.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not sure if it sane to do this indepent of the phase
|
||||
* but, here we go...
|
||||
*
|
||||
* This code cames from: http/ngx_http_special_response.c
|
||||
* function: ngx_http_send_error_page
|
||||
* src/http/ngx_http_core_module.c
|
||||
* From src/http/ngx_http_core_module.c (line 1910) i learnt
|
||||
* that location->hash should be set to 1.
|
||||
*
|
||||
*/
|
||||
ngx_http_clear_location(r);
|
||||
ngx_str_t a = ngx_string("");
|
||||
|
||||
a.data = (unsigned char *)intervention.url;
|
||||
a.len = strlen(intervention.url);
|
||||
|
||||
ngx_table_elt_t *location = NULL;
|
||||
location = ngx_list_push(&r->headers_out.headers);
|
||||
ngx_str_set(&location->key, "Location");
|
||||
location->value = a;
|
||||
r->headers_out.location = location;
|
||||
r->headers_out.location->hash = 1;
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_http_modsecurity_store_ctx_header(r, &location->key, &location->value);
|
||||
#endif
|
||||
|
||||
return intervention.status;
|
||||
}
|
||||
|
||||
if (intervention.status != 200)
|
||||
{
|
||||
/**
|
||||
* FIXME: this will bring proper response code to audit log in case
|
||||
* when e.g. error_page redirect was triggered, but there still won't be another
|
||||
* required pieces like response headers etc.
|
||||
*
|
||||
*/
|
||||
msc_update_status_code(ctx->modsec_transaction, intervention.status);
|
||||
|
||||
if (early_log) {
|
||||
dd("intervention -- calling log handler manually with code: %d", intervention.status);
|
||||
ngx_http_modsecurity_log_handler(r);
|
||||
ctx->logged = 1;
|
||||
}
|
||||
|
||||
if (r->header_sent)
|
||||
{
|
||||
dd("Headers are already sent. Cannot perform the redirection at this point.");
|
||||
return -1;
|
||||
}
|
||||
dd("intervention -- returning code: %d", intervention.status);
|
||||
return intervention.status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_modsecurity_cleanup(void *data)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
|
||||
ctx = (ngx_http_modsecurity_ctx_t *) data;
|
||||
|
||||
msc_transaction_cleanup(ctx->modsec_transaction);
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
/*
|
||||
* Purge stored context headers. Memory allocated for individual stored header
|
||||
* name/value pair will be freed automatically when r->pool is destroyed.
|
||||
*/
|
||||
ngx_array_destroy(ctx->sanity_headers_out);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ngx_inline ngx_http_modsecurity_ctx_t *
|
||||
ngx_http_modsecurity_create_ctx(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_str_t s;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
ngx_http_modsecurity_main_conf_t *mmcf;
|
||||
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_modsecurity_ctx_t));
|
||||
if (ctx == NULL)
|
||||
{
|
||||
dd("failed to allocate memory for the context.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mmcf = ngx_http_get_module_main_conf(r, ngx_http_modsecurity_module);
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("creating transaction with the following rules: '%p' -- ms: '%p'", mcf->rules_set, mmcf->modsec);
|
||||
|
||||
if (mcf->transaction_id) {
|
||||
if (ngx_http_complex_value(r, mcf->transaction_id, &s) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
ctx->modsec_transaction = msc_new_transaction_with_id(mmcf->modsec, mcf->rules_set, (char *) s.data, r->connection->log);
|
||||
|
||||
} else {
|
||||
ctx->modsec_transaction = msc_new_transaction(mmcf->modsec, mcf->rules_set, r->connection->log);
|
||||
}
|
||||
|
||||
dd("transaction created");
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_modsecurity_module);
|
||||
|
||||
cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_modsecurity_ctx_t));
|
||||
if (cln == NULL)
|
||||
{
|
||||
dd("failed to create the ModSecurity context cleanup");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
cln->handler = ngx_http_modsecurity_cleanup;
|
||||
cln->data = ctx;
|
||||
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ctx->sanity_headers_out = ngx_array_create(r->pool, 12, sizeof(ngx_http_modsecurity_header_t));
|
||||
if (ctx->sanity_headers_out == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_set_rules(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
int res;
|
||||
char *rules;
|
||||
ngx_str_t *value;
|
||||
const char *error;
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_conf_t *mcf = conf;
|
||||
ngx_http_modsecurity_main_conf_t *mmcf;
|
||||
|
||||
value = cf->args->elts;
|
||||
rules = ngx_str_to_char(value[1], cf->pool);
|
||||
|
||||
if (rules == (char *)-1) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(cf->pool);
|
||||
res = msc_rules_add(mcf->rules_set, rules, &error);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
if (res < 0) {
|
||||
dd("Failed to load the rules: '%s' - reason: '%s'", rules, error);
|
||||
return strdup(error);
|
||||
}
|
||||
|
||||
mmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_modsecurity_module);
|
||||
mmcf->rules_inline += res;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_set_rules_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
int res;
|
||||
char *rules_set;
|
||||
ngx_str_t *value;
|
||||
const char *error;
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_conf_t *mcf = conf;
|
||||
ngx_http_modsecurity_main_conf_t *mmcf;
|
||||
|
||||
value = cf->args->elts;
|
||||
rules_set = ngx_str_to_char(value[1], cf->pool);
|
||||
|
||||
if (rules_set == (char *)-1) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(cf->pool);
|
||||
res = msc_rules_add_file(mcf->rules_set, rules_set, &error);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
if (res < 0) {
|
||||
dd("Failed to load the rules from: '%s' - reason: '%s'", rules_set, error);
|
||||
return strdup(error);
|
||||
}
|
||||
|
||||
mmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_modsecurity_module);
|
||||
mmcf->rules_file += res;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_set_rules_remote(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
int res;
|
||||
ngx_str_t *value;
|
||||
const char *error;
|
||||
const char *rules_remote_key, *rules_remote_server;
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_conf_t *mcf = conf;
|
||||
ngx_http_modsecurity_main_conf_t *mmcf;
|
||||
|
||||
value = cf->args->elts;
|
||||
rules_remote_key = ngx_str_to_char(value[1], cf->pool);
|
||||
rules_remote_server = ngx_str_to_char(value[2], cf->pool);
|
||||
|
||||
if (rules_remote_server == (char *)-1) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rules_remote_key == (char *)-1) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(cf->pool);
|
||||
res = msc_rules_add_remote(mcf->rules_set, rules_remote_key, rules_remote_server, &error);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
if (res < 0) {
|
||||
dd("Failed to load the rules from: '%s' - reason: '%s'", rules_remote_server, error);
|
||||
return strdup(error);
|
||||
}
|
||||
|
||||
mmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_modsecurity_module);
|
||||
mmcf->rules_remote += res;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
char *ngx_conf_set_transaction_id(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
|
||||
ngx_str_t *value;
|
||||
ngx_http_complex_value_t cv;
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
ngx_http_modsecurity_conf_t *mcf = conf;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
|
||||
|
||||
ccv.cf = cf;
|
||||
ccv.value = &value[1];
|
||||
ccv.complex_value = &cv;
|
||||
ccv.zero = 1;
|
||||
|
||||
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
mcf->transaction_id = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
|
||||
if (mcf->transaction_id == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*mcf->transaction_id = cv;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_modsecurity_commands[] = {
|
||||
{
|
||||
ngx_string("modsecurity"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_modsecurity_conf_t, enable),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
ngx_string("modsecurity_rules"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_rules,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_modsecurity_conf_t, enable),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
ngx_string("modsecurity_rules_file"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_rules_file,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_modsecurity_conf_t, enable),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
ngx_string("modsecurity_rules_remote"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
|
||||
ngx_conf_set_rules_remote,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_modsecurity_conf_t, enable),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
ngx_string("modsecurity_transaction_id"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_MAIN_CONF|NGX_CONF_1MORE,
|
||||
ngx_conf_set_transaction_id,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_http_modsecurity_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
ngx_http_modsecurity_init, /* postconfiguration */
|
||||
|
||||
ngx_http_modsecurity_create_main_conf, /* create main configuration */
|
||||
ngx_http_modsecurity_init_main_conf, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
ngx_http_modsecurity_create_conf, /* create location configuration */
|
||||
ngx_http_modsecurity_merge_conf /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_http_modsecurity_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_modsecurity_ctx, /* module context */
|
||||
ngx_http_modsecurity_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_modsecurity_init(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_handler_pt *h_rewrite;
|
||||
ngx_http_handler_pt *h_access;
|
||||
ngx_http_handler_pt *h_log;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
int rc = 0;
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
if (cmcf == NULL)
|
||||
{
|
||||
dd("We are not sure how this returns, NGINX doesn't seem to think it will ever be null");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Seems like we cannot do this very same thing with
|
||||
* NGX_HTTP_FIND_CONFIG_PHASE. it does not seems to
|
||||
* be an array. Our next option is the REWRITE.
|
||||
*
|
||||
* TODO: check if we can hook prior to NGX_HTTP_REWRITE_PHASE phase.
|
||||
*
|
||||
*/
|
||||
h_rewrite = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
|
||||
if (h_rewrite == NULL)
|
||||
{
|
||||
dd("Not able to create a new NGX_HTTP_REWRITE_PHASE handle");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
*h_rewrite = ngx_http_modsecurity_rewrite_handler;
|
||||
|
||||
/**
|
||||
*
|
||||
* Processing the request body on the access phase.
|
||||
*
|
||||
* TODO: check if hook into separated phases is the best thing to do.
|
||||
*
|
||||
*/
|
||||
h_access = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
|
||||
if (h_access == NULL)
|
||||
{
|
||||
dd("Not able to create a new NGX_HTTP_ACCESS_PHASE handle");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
*h_access = ngx_http_modsecurity_access_handler;
|
||||
|
||||
/**
|
||||
* Process the log phase.
|
||||
*
|
||||
* TODO: check if the log phase happens like it happens on Apache.
|
||||
* check if last phase will not hold the request.
|
||||
*
|
||||
*/
|
||||
h_log = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
|
||||
if (h_log == NULL)
|
||||
{
|
||||
dd("Not able to create a new NGX_HTTP_LOG_PHASE handle");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
*h_log = ngx_http_modsecurity_log_handler;
|
||||
|
||||
|
||||
rc = ngx_http_modsecurity_header_filter_init();
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ngx_http_modsecurity_body_filter_init();
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_modsecurity_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_http_modsecurity_main_conf_t *conf;
|
||||
|
||||
conf = (ngx_http_modsecurity_main_conf_t *) ngx_pcalloc(cf->pool,
|
||||
sizeof(ngx_http_modsecurity_main_conf_t));
|
||||
|
||||
if (conf == NULL)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->modsec = NULL;
|
||||
* conf->pool = NULL;
|
||||
* conf->rules_inline = 0;
|
||||
* conf->rules_file = 0;
|
||||
* conf->rules_remote = 0;
|
||||
*/
|
||||
|
||||
cln = ngx_pool_cleanup_add(cf->pool, 0);
|
||||
if (cln == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cln->handler = ngx_http_modsecurity_cleanup_instance;
|
||||
cln->data = conf;
|
||||
|
||||
conf->pool = cf->pool;
|
||||
|
||||
/* Create our ModSecurity instance */
|
||||
conf->modsec = msc_init();
|
||||
if (conf->modsec == NULL)
|
||||
{
|
||||
dd("failed to create the ModSecurity instance");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/* Provide our connector information to LibModSecurity */
|
||||
msc_set_connector_info(conf->modsec, MODSECURITY_NGINX_WHOAMI);
|
||||
msc_set_log_cb(conf->modsec, ngx_http_modsecurity_log);
|
||||
|
||||
dd ("main conf created at: '%p', instance is: '%p'", conf, conf->modsec);
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_modsecurity_init_main_conf(ngx_conf_t *cf, void *conf)
|
||||
{
|
||||
ngx_http_modsecurity_main_conf_t *mmcf;
|
||||
mmcf = (ngx_http_modsecurity_main_conf_t *) conf;
|
||||
|
||||
ngx_log_error(NGX_LOG_NOTICE, cf->log, 0,
|
||||
"%s (rules loaded inline/local/remote: %ui/%ui/%ui)",
|
||||
MODSECURITY_NGINX_WHOAMI, mmcf->rules_inline,
|
||||
mmcf->rules_file, mmcf->rules_remote);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_modsecurity_create_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_http_modsecurity_conf_t *conf;
|
||||
|
||||
conf = (ngx_http_modsecurity_conf_t *) ngx_pcalloc(cf->pool,
|
||||
sizeof(ngx_http_modsecurity_conf_t));
|
||||
|
||||
if (conf == NULL)
|
||||
{
|
||||
dd("Failed to allocate space for ModSecurity configuration");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->enable = 0;
|
||||
* conf->sanity_checks_enabled = 0;
|
||||
* conf->rules_set = NULL;
|
||||
* conf->pool = NULL;
|
||||
* conf->transaction_id = NULL;
|
||||
*/
|
||||
|
||||
conf->enable = NGX_CONF_UNSET;
|
||||
conf->rules_set = msc_create_rules_set();
|
||||
conf->pool = cf->pool;
|
||||
conf->transaction_id = NGX_CONF_UNSET_PTR;
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
conf->sanity_checks_enabled = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
cln = ngx_pool_cleanup_add(cf->pool, 0);
|
||||
if (cln == NULL) {
|
||||
dd("failed to create the ModSecurity configuration cleanup");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cln->handler = ngx_http_modsecurity_cleanup_rules;
|
||||
cln->data = conf;
|
||||
|
||||
dd ("conf created at: '%p'", conf);
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_http_modsecurity_conf_t *p = parent;
|
||||
ngx_http_modsecurity_conf_t *c = child;
|
||||
#if defined(MODSECURITY_DDEBUG) && (MODSECURITY_DDEBUG)
|
||||
ngx_http_core_loc_conf_t *clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
#endif
|
||||
int rules;
|
||||
const char *error = NULL;
|
||||
|
||||
dd("merging loc config [%s] - parent: '%p' child: '%p'",
|
||||
ngx_str_to_char(clcf->name, cf->pool), parent,
|
||||
child);
|
||||
|
||||
dd(" state - parent: '%d' child: '%d'",
|
||||
(int) c->enable, (int) p->enable);
|
||||
|
||||
ngx_conf_merge_value(c->enable, p->enable, 0);
|
||||
ngx_conf_merge_ptr_value(c->transaction_id, p->transaction_id, NULL);
|
||||
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
|
||||
ngx_conf_merge_value(c->sanity_checks_enabled, p->sanity_checks_enabled, 0);
|
||||
#endif
|
||||
|
||||
#if defined(MODSECURITY_DDEBUG) && (MODSECURITY_DDEBUG)
|
||||
dd("PARENT RULES");
|
||||
msc_rules_dump(p->rules_set);
|
||||
dd("CHILD RULES");
|
||||
msc_rules_dump(c->rules_set);
|
||||
#endif
|
||||
rules = msc_rules_merge(c->rules_set, p->rules_set, &error);
|
||||
|
||||
if (rules < 0) {
|
||||
return strdup(error);
|
||||
}
|
||||
|
||||
#if defined(MODSECURITY_DDEBUG) && (MODSECURITY_DDEBUG)
|
||||
dd("NEW CHILD RULES");
|
||||
msc_rules_dump(c->rules_set);
|
||||
#endif
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_modsecurity_cleanup_instance(void *data)
|
||||
{
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_main_conf_t *mmcf;
|
||||
|
||||
mmcf = (ngx_http_modsecurity_main_conf_t *) data;
|
||||
|
||||
dd("deleting a main conf -- instance is: \"%p\"", mmcf->modsec);
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(mmcf->pool);
|
||||
msc_cleanup(mmcf->modsec);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_modsecurity_cleanup_rules(void *data)
|
||||
{
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
|
||||
mcf = (ngx_http_modsecurity_conf_t *) data;
|
||||
|
||||
dd("deleting a loc conf -- RuleSet is: \"%p\"", mcf->rules_set);
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(mcf->pool);
|
||||
msc_rules_cleanup(mcf->rules_set);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
}
|
||||
|
||||
|
||||
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
|
||||
void
|
||||
ngx_http_modsecurity_request_read(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
#if defined(nginx_version) && nginx_version >= 8011
|
||||
r->main->count--;
|
||||
#endif
|
||||
|
||||
if (ctx->waiting_more_body)
|
||||
{
|
||||
ctx->waiting_more_body = 0;
|
||||
r->write_event_handler = ngx_http_core_run_phases;
|
||||
ngx_http_core_run_phases(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
|
||||
{
|
||||
#if 1
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
|
||||
dd("catching a new _preaccess_ phase handler");
|
||||
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
if (mcf == NULL || mcf->enable != 1)
|
||||
{
|
||||
dd("ModSecurity not enabled... returning");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
/*
|
||||
* FIXME:
|
||||
* In order to perform some tests, let's accept everything.
|
||||
*
|
||||
if (r->method != NGX_HTTP_GET &&
|
||||
r->method != NGX_HTTP_POST && r->method != NGX_HTTP_HEAD) {
|
||||
dd("ModSecurity is not ready to deal with anything different from " \
|
||||
"POST, GET or HEAD");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
*/
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("recovering ctx: %p", ctx);
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
dd("ctx is null; Nothing we can do, returning an error.");
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->intervention_triggered) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (ctx->waiting_more_body == 1)
|
||||
{
|
||||
dd("waiting for more data before proceed. / count: %d",
|
||||
r->main->count);
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
if (ctx->body_requested == 0)
|
||||
{
|
||||
ngx_int_t rc = NGX_OK;
|
||||
|
||||
ctx->body_requested = 1;
|
||||
|
||||
dd("asking for the request body, if any. Count: %d",
|
||||
r->main->count);
|
||||
/**
|
||||
* TODO: Check if there is any benefit to use request_body_in_single_buf set to 1.
|
||||
*
|
||||
* saw some module using this request_body_in_single_buf
|
||||
* but not sure what exactly it does, same for the others options below.
|
||||
*
|
||||
* r->request_body_in_single_buf = 1;
|
||||
*/
|
||||
r->request_body_in_single_buf = 1;
|
||||
r->request_body_in_persistent_file = 1;
|
||||
if (!r->request_body_in_file_only) {
|
||||
// If the above condition fails, then the flag below will have been
|
||||
// set correctly elsewhere. We need to set the flag here for other
|
||||
// conditions (client_body_in_file_only not used but
|
||||
// client_body_buffer_size is)
|
||||
r->request_body_in_clean_file = 1;
|
||||
}
|
||||
|
||||
rc = ngx_http_read_client_request_body(r,
|
||||
ngx_http_modsecurity_request_read);
|
||||
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
#if (nginx_version < 1002006) || \
|
||||
(nginx_version >= 1003000 && nginx_version < 1003009)
|
||||
r->main->count--;
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
if (rc == NGX_AGAIN)
|
||||
{
|
||||
dd("nginx is asking us to wait for more data.");
|
||||
|
||||
ctx->waiting_more_body = 1;
|
||||
return NGX_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->waiting_more_body == 0)
|
||||
{
|
||||
int ret = 0;
|
||||
int already_inspected = 0;
|
||||
|
||||
dd("request body is ready to be processed");
|
||||
|
||||
r->write_event_handler = ngx_http_core_run_phases;
|
||||
|
||||
ngx_chain_t *chain = r->request_body->bufs;
|
||||
|
||||
/**
|
||||
* TODO: Speed up the analysis by sending chunk while they arrive.
|
||||
*
|
||||
* Notice that we are waiting for the full request body to
|
||||
* start to process it, it may not be necessary. We may send
|
||||
* the chunks to ModSecurity while nginx keep calling this
|
||||
* function.
|
||||
*/
|
||||
|
||||
if (r->request_body->temp_file != NULL) {
|
||||
ngx_str_t file_path = r->request_body->temp_file->file.name;
|
||||
const char *file_name = ngx_str_to_char(file_path, r->pool);
|
||||
if (file_name == (char*)-1) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
/*
|
||||
* Request body was saved to a file, probably we don't have a
|
||||
* copy of it in memory.
|
||||
*/
|
||||
dd("request body inspection: file -- %s", file_name);
|
||||
|
||||
msc_request_body_from_file(ctx->modsec_transaction, file_name);
|
||||
|
||||
already_inspected = 1;
|
||||
} else {
|
||||
dd("inspection request body in memory.");
|
||||
}
|
||||
|
||||
while (chain && !already_inspected)
|
||||
{
|
||||
u_char *data = chain->buf->pos;
|
||||
|
||||
msc_append_request_body(ctx->modsec_transaction, data,
|
||||
chain->buf->last - data);
|
||||
|
||||
if (chain->buf->last_buf) {
|
||||
break;
|
||||
}
|
||||
chain = chain->next;
|
||||
|
||||
/* XXX: chains are processed one-by-one, maybe worth to pass all chains and then call intervention() ? */
|
||||
|
||||
/**
|
||||
* ModSecurity may perform stream inspection on this buffer,
|
||||
* it may ask for a intervention in consequence of that.
|
||||
*
|
||||
*/
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* At this point, all the request body was sent to ModSecurity
|
||||
* and we want to make sure that all the request body inspection
|
||||
* happened; consequently we have to check if ModSecurity have
|
||||
* returned any kind of intervention.
|
||||
*/
|
||||
|
||||
/* XXX: once more -- is body can be modified ? content-length need to be adjusted ? */
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_request_body(ctx->modsec_transaction);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
|
||||
if (r->error_page) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dd("Nothing to add on the body inspection, reclaiming a NGX_DECLINED");
|
||||
#endif
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* ModSecurity connector for nginx, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MODSECURITY_DDEBUG
|
||||
#define MODSECURITY_DDEBUG 0
|
||||
#endif
|
||||
#include "ddebug.h"
|
||||
|
||||
#include "ngx_http_modsecurity_common.h"
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_pool_t *old_pool;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
ngx_http_modsecurity_conf_t *mcf;
|
||||
|
||||
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
||||
if (mcf == NULL || mcf->enable != 1) {
|
||||
dd("ModSecurity not enabled... returning");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
/*
|
||||
if (r->method != NGX_HTTP_GET &&
|
||||
r->method != NGX_HTTP_POST && r->method != NGX_HTTP_HEAD) {
|
||||
dd("ModSecurity is not ready to deal with anything different from " \
|
||||
"POST, GET or HEAD");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
*/
|
||||
|
||||
dd("catching a new _rewrite_ phase handler");
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
|
||||
|
||||
dd("recovering ctx: %p", ctx);
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ngx_connection_t *connection = r->connection;
|
||||
/**
|
||||
* FIXME: We may want to use struct sockaddr instead of addr_text.
|
||||
*
|
||||
*/
|
||||
ngx_str_t addr_text = connection->addr_text;
|
||||
|
||||
ctx = ngx_http_modsecurity_create_ctx(r);
|
||||
|
||||
dd("ctx was NULL, creating new context: %p", ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
dd("ctx still null; Nothing we can do, returning an error.");
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: Check if it is possible to hook on nginx on a earlier phase.
|
||||
*
|
||||
* At this point we are doing an late connection process. Maybe
|
||||
* we have to hook into NGX_HTTP_FIND_CONFIG_PHASE, it seems to be the
|
||||
* erliest phase that nginx allow us to attach those kind of hooks.
|
||||
*
|
||||
*/
|
||||
int client_port = ngx_inet_get_port(connection->sockaddr);
|
||||
int server_port = ngx_inet_get_port(connection->local_sockaddr);
|
||||
|
||||
const char *client_addr = ngx_str_to_char(addr_text, r->pool);
|
||||
if (client_addr == (char*)-1) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ngx_str_t s;
|
||||
u_char addr[NGX_SOCKADDR_STRLEN];
|
||||
s.len = NGX_SOCKADDR_STRLEN;
|
||||
s.data = addr;
|
||||
if (ngx_connection_local_sockaddr(r->connection, &s, 0) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
const char *server_addr = ngx_str_to_char(s, r->pool);
|
||||
if (server_addr == (char*)-1) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
ret = msc_process_connection(ctx->modsec_transaction,
|
||||
client_addr, client_port,
|
||||
server_addr, server_port);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
if (ret != 1){
|
||||
dd("Was not able to extract connection information.");
|
||||
}
|
||||
/**
|
||||
*
|
||||
* FIXME: Check how we can finalize a request without crash nginx.
|
||||
*
|
||||
* I don't think nginx is expecting to finalize a request at that
|
||||
* point as it seems that it clean the ngx_http_request_t information
|
||||
* and try to use it later.
|
||||
*
|
||||
*/
|
||||
dd("Processing intervention with the connection information filled in");
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 1);
|
||||
if (ret > 0) {
|
||||
ctx->intervention_triggered = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *http_version;
|
||||
switch (r->http_version) {
|
||||
case NGX_HTTP_VERSION_9 :
|
||||
http_version = "0.9";
|
||||
break;
|
||||
case NGX_HTTP_VERSION_10 :
|
||||
http_version = "1.0";
|
||||
break;
|
||||
case NGX_HTTP_VERSION_11 :
|
||||
http_version = "1.1";
|
||||
break;
|
||||
#if defined(nginx_version) && nginx_version >= 1009005
|
||||
case NGX_HTTP_VERSION_20 :
|
||||
http_version = "2.0";
|
||||
break;
|
||||
#endif
|
||||
default :
|
||||
http_version = ngx_str_to_char(r->http_protocol, r->pool);
|
||||
if (http_version == (char*)-1) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if ((http_version != NULL) && (strlen(http_version) > 5) && (!strncmp("HTTP/", http_version, 5))) {
|
||||
http_version += 5;
|
||||
} else {
|
||||
http_version = "1.0";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
const char *n_uri = ngx_str_to_char(r->unparsed_uri, r->pool);
|
||||
const char *n_method = ngx_str_to_char(r->method_name, r->pool);
|
||||
if (n_uri == (char*)-1 || n_method == (char*)-1) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (n_uri == NULL) {
|
||||
dd("uri is of length zero");
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_uri(ctx->modsec_transaction, n_uri, n_method, http_version);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
|
||||
dd("Processing intervention with the transaction information filled in (uri, method and version)");
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 1);
|
||||
if (ret > 0) {
|
||||
ctx->intervention_triggered = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since incoming request headers are already in place, lets send it to ModSecurity
|
||||
*
|
||||
*/
|
||||
ngx_list_part_t *part = &r->headers_in.headers.part;
|
||||
ngx_table_elt_t *data = part->elts;
|
||||
ngx_uint_t i = 0;
|
||||
for (i = 0 ; /* void */ ; i++) {
|
||||
if (i >= part->nelts) {
|
||||
if (part->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
part = part->next;
|
||||
data = part->elts;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* By using u_char (utf8_t) I believe nginx is hoping to deal
|
||||
* with utf8 strings.
|
||||
* Casting those into to unsigned char * in order to pass
|
||||
* it to ModSecurity, it will handle with those later.
|
||||
*
|
||||
*/
|
||||
|
||||
dd("Adding request header: %.*s with value %.*s", (int)data[i].key.len, data[i].key.data, (int) data[i].value.len, data[i].value.data);
|
||||
msc_add_n_request_header(ctx->modsec_transaction,
|
||||
(const unsigned char *) data[i].key.data,
|
||||
data[i].key.len,
|
||||
(const unsigned char *) data[i].value.data,
|
||||
data[i].value.len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since ModSecurity already knew about all headers, i guess it is safe
|
||||
* to process this information.
|
||||
*/
|
||||
|
||||
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
|
||||
msc_process_request_headers(ctx->modsec_transaction);
|
||||
ngx_http_modsecurity_pcre_malloc_done(old_pool);
|
||||
dd("Processing intervention with the request headers information filled in");
|
||||
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 1);
|
||||
if (r->error_page) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
if (ret > 0) {
|
||||
ctx->intervention_triggered = 1;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
# Tests
|
||||
|
||||
Those are nginx test files. You can copy those files into yours nginx test
|
||||
tree, to perform the tests using the "prove" utility.
|
||||
|
||||
For more information about those tests, read the subsection "Testing your
|
||||
patch" on the project's README file.
|
||||
|
||||
For more about nginx tests, check their repository:
|
||||
http://hg.nginx.org/nginx-tests/
|
|
@ -1,233 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# ModSecurity, http://www.modsecurity.org/
|
||||
# Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
#
|
||||
# You may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# If any of the files related to licensing are missing or if you have any
|
||||
# other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
# directly using the email address security@modsecurity.org.
|
||||
#
|
||||
|
||||
|
||||
# Tests for ModSecurity module.
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq whee" "id:10,phase:2"
|
||||
SecRule ARGS "@streq whee" "id:11,phase:2"
|
||||
';
|
||||
|
||||
location / {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq root" "id:21,phase:1,auditlog,status:302,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-root.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts AB
|
||||
SecAuditLog %%TESTDIR%%/auditlog-root.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
}
|
||||
|
||||
location /subfolder1/subfolder2 {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq subfolder2" "id:41,phase:1,status:302,auditlog,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq subfolder1" "id:42,phase:1,status:302,auditlog,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-subfolder2.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts AB
|
||||
SecResponseBodyAccess On
|
||||
SecAuditLog %%TESTDIR%%/auditlog-subfolder2.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
}
|
||||
|
||||
location /subfolder1 {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq subfolder1" "id:31,phase:1,status:302,auditlog,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-subfolder1.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogParts AB
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog %%TESTDIR%%/auditlog-subfolder1.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
}
|
||||
|
||||
location /subfolder3/subfolder4 {
|
||||
modsecurity_rules '
|
||||
SecResponseBodyAccess On
|
||||
SecRule ARGS "@streq subfolder4" "id:61,phase:1,status:302,auditlog,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq subfolder3" "id:62,phase:1,status:302,auditlog,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq subfolder4withE" "id:63,phase:1,ctl:auditLogParts=+E,auditlog"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-subfolder4.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts AB
|
||||
SecAuditLog %%TESTDIR%%/auditlog-subfolder4.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
}
|
||||
|
||||
location /subfolder3 {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq subfolder3" "id:51,phase:1,status:302,auditlog,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-subfolder3.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogParts AB
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog %%TESTDIR%%/auditlog-subfolder3.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder1');
|
||||
$t->write_file("/subfolder1/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder1/subfolder2');
|
||||
$t->write_file("/subfolder1/subfolder2/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder3');
|
||||
$t->write_file("/subfolder3/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder3/subfolder4');
|
||||
$t->write_file("/subfolder3/subfolder4/index.html", "should be moved/blocked before this.");
|
||||
|
||||
$t->run();
|
||||
$t->plan(9);
|
||||
|
||||
###############################################################################
|
||||
|
||||
my $d = $t->testdir();
|
||||
|
||||
my $r;
|
||||
# Performing requests at root
|
||||
$r = http_get('/index.html?what=root');
|
||||
$r = http_get('/index.html?what=subfolder1');
|
||||
$r = http_get('/index.html?what=subfolder2');
|
||||
$r = http_get('/index.html?what=subfolder3');
|
||||
$r = http_get('/index.html?what=subfolder4');
|
||||
|
||||
# Performing requests at subfolder1
|
||||
$r = http_get('/subfolder1/index.html?what=root');
|
||||
$r = http_get('/subfolder1/index.html?what=subfolder1');
|
||||
$r = http_get('/subfolder1/index.html?what=subfolder2');
|
||||
$r = http_get('/subfolder1/index.html?what=subfolder3');
|
||||
$r = http_get('/subfolder1/index.html?what=subfolder4');
|
||||
|
||||
# Performing requests at subfolder2
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=root');
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=subfolder1');
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=subfolder2');
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=subfolder3');
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=subfolder4');
|
||||
|
||||
# Performing requests at subfolder3
|
||||
$r = http_get('/subfolder3/index.html?what=root');
|
||||
$r = http_get('/subfolder3/index.html?what=subfolder1');
|
||||
$r = http_get('/subfolder3/index.html?what=subfolder2');
|
||||
$r = http_get('/subfolder3/index.html?what=subfolder3');
|
||||
$r = http_get('/subfolder3/index.html?what=subfolder4');
|
||||
|
||||
# Performing requests at subfolder4
|
||||
$r = http_get('/subfolder3/subfolder4/index.html?what=root');
|
||||
$r = http_get('/subfolder3/subfolder4/index.html?what=subfolder1');
|
||||
$r = http_get('/subfolder3/subfolder4/index.html?what=subfolder2');
|
||||
$r = http_get('/subfolder3/subfolder4/index.html?what=subfolder3');
|
||||
$r = http_get('/subfolder3/subfolder4/index.html?what=subfolder4');
|
||||
$r = http_get('/subfolder3/subfolder4/index.html?what=subfolder4withE');
|
||||
|
||||
my $root = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-root.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
my $subfolder1 = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-subfolder1.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
my $subfolder2 = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-subfolder2.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
my $subfolder3 = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-subfolder3.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
my $subfolder4 = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-subfolder4.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
|
||||
|
||||
like($root, qr/what=root/, 'root');
|
||||
like($subfolder1, qr/what=subfolder1/, 'subfolder1');
|
||||
like($subfolder2, qr/what=subfolder2/, 'subfolder2');
|
||||
like($subfolder2, qr/what=subfolder1/, 'subfolder2 / subfolder1');
|
||||
|
||||
like($subfolder3, qr/what=subfolder3/, 'subfolder3');
|
||||
like($subfolder4, qr/what=subfolder4/, 'subfolder4');
|
||||
like($subfolder4, qr/what=subfolder3/, 'subfolder4 / subfolder3');
|
||||
|
||||
like($subfolder4, qr/what=subfolder4withE/, 'subfolder4');
|
||||
like($subfolder4, qr/---E--/, 'subfolder4');
|
|
@ -1,174 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# ModSecurity, http://www.modsecurity.org/
|
||||
# Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
#
|
||||
# You may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# If any of the files related to licensing are missing or if you have any
|
||||
# other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
# directly using the email address security@modsecurity.org.
|
||||
#
|
||||
|
||||
|
||||
# Tests for ModSecurity module.
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name s1;
|
||||
|
||||
error_page 403 /403.html;
|
||||
|
||||
location /403.html {
|
||||
root %%TESTDIR%%/http;
|
||||
internal;
|
||||
}
|
||||
|
||||
location / {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq root" "id:10,phase:1,auditlog,status:403,deny"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-local.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog %%TESTDIR%%/auditlog-local.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name s2;
|
||||
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq root" "id:10,phase:1,auditlog,status:403,deny"
|
||||
SecDebugLog %%TESTDIR%%/auditlog-debug-global.txt
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog %%TESTDIR%%/auditlog-global.txt
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
';
|
||||
|
||||
error_page 403 /403.html;
|
||||
|
||||
location /403.html {
|
||||
modsecurity off;
|
||||
root %%TESTDIR%%/http;
|
||||
internal;
|
||||
}
|
||||
|
||||
location / {
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
my $index_txt = "This is the index page.";
|
||||
my $custom_txt = "This is a custom error page.";
|
||||
|
||||
$t->write_file("/index.html", $index_txt);
|
||||
mkdir($t->testdir() . '/http');
|
||||
$t->write_file("/http/403.html", $custom_txt);
|
||||
|
||||
$t->run();
|
||||
$t->plan(10);
|
||||
|
||||
###############################################################################
|
||||
|
||||
my $d = $t->testdir();
|
||||
|
||||
my $t1;
|
||||
my $t2;
|
||||
my $t3;
|
||||
my $t4;
|
||||
|
||||
# Performing requests to a server with ModSecurity enabled at location context
|
||||
$t1 = http_get_host('s1', '/index.html?what=root');
|
||||
$t2 = http_get_host('s1', '/index.html?what=other');
|
||||
|
||||
# Performing requests to a server with ModSecurity enabled at server context
|
||||
$t3 = http_get_host('s2', '/index.html?what=root');
|
||||
$t4 = http_get_host('s2', '/index.html?what=other');
|
||||
|
||||
my $local = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-local.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
|
||||
my $global = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/auditlog-global.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
|
||||
like($t1, qr/$custom_txt/, 'ModSecurity at location / root');
|
||||
like($t2, qr/$index_txt/, 'ModSecurity at location / other');
|
||||
like($local, qr/what=root/, 'ModSecurity at location / root present in auditlog');
|
||||
unlike($local, qr/what=other/, 'ModSecurity at location / other not present in auditlog');
|
||||
|
||||
like($t3, qr/$custom_txt/, 'ModSecurity at server / root');
|
||||
like($t4, qr/$index_txt/, 'ModSecurity at server / other');
|
||||
like($global, qr/what=root/, 'ModSecurity at server / root present in auditlog');
|
||||
unlike($global, qr/what=other/, 'ModSecurity at server / other not present in auditlog');
|
||||
|
||||
like($local, qr/Access denied with code 403/, 'ModSecurity at location / 403 in auditlog');
|
||||
like($global, qr/Access denied with code 403/, 'ModSecurity at server / 403 in auditlog');
|
||||
|
||||
###############################################################################
|
||||
|
||||
sub http_get_host {
|
||||
my ($host, $url) = @_;
|
||||
return http(<<EOF);
|
||||
GET $url HTTP/1.0
|
||||
Host: $host
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,142 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# ModSecurity, http://www.modsecurity.org/
|
||||
# Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
#
|
||||
# You may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# If any of the files related to licensing are missing or if you have any
|
||||
# other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
# directly using the email address security@modsecurity.org.
|
||||
#
|
||||
|
||||
|
||||
# Tests for ModSecurity module.
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq whee" "id:10,phase:2"
|
||||
SecRule ARGS "@streq whee" "id:11,phase:2"
|
||||
';
|
||||
|
||||
location / {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq root" "id:21,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/debuglog-root.txt
|
||||
SecDebugLogLevel 9
|
||||
';
|
||||
}
|
||||
|
||||
location /subfolder1 {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq subfolder1" "id:31,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/debuglog-subfolder1.txt
|
||||
SecDebugLogLevel 9
|
||||
';
|
||||
location /subfolder1/subfolder2 {
|
||||
modsecurity_rules '
|
||||
SecRule ARGS "@streq subfolder2" "id:41,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecDebugLog %%TESTDIR%%/debuglog-subfolder2.txt
|
||||
SecDebugLogLevel 9
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder1');
|
||||
$t->write_file("/subfolder1/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder1/subfolder2');
|
||||
$t->write_file("/subfolder1/subfolder2/index.html", "should be moved/blocked before this.");
|
||||
|
||||
$t->run();
|
||||
$t->plan(3);
|
||||
|
||||
###############################################################################
|
||||
|
||||
my $d = $t->testdir();
|
||||
|
||||
my $r;
|
||||
# Performing requests at root
|
||||
$r = http_get('/index.html?what=root');
|
||||
$r = http_get('/index.html?what=subfolder1');
|
||||
$r = http_get('/index.html?what=subfolder2');
|
||||
|
||||
# Performing requests at subfolder1
|
||||
$r = http_get('/subfolder1/index.html?what=root');
|
||||
$r = http_get('/subfolder1/index.html?what=subfolder1');
|
||||
$r = http_get('/subfolder1/index.html?what=subfolder2');
|
||||
|
||||
# Performing requests at subfolder2
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=root');
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=subfolder1');
|
||||
$r = http_get('/subfolder1/subfolder2/index.html?what=subfolder2');
|
||||
|
||||
my $root = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/debuglog-root.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
my $subfolder1 = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/debuglog-subfolder1.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
my $subfolder2 = do {
|
||||
local $/ = undef;
|
||||
open my $fh, "<", "$d/debuglog-subfolder2.txt"
|
||||
or die "could not open: $!";
|
||||
<$fh>;
|
||||
};
|
||||
|
||||
like($root, qr/"what", value "root"/, 'root');
|
||||
like($subfolder1, qr/"what", value "subfolder1"/, 'subfolder1');
|
||||
like($subfolder2, qr/"what", value "subfolder2"/, 'subfolder2');
|
||||
|
||||
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity-nginx connector (configuration merge).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
use Socket qw/ CRLF /;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http proxy/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRequestBodyLimit 128
|
||||
SecRequestBodyLimitAction Reject
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:11,phase:request,deny,log,status:403"
|
||||
';
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:%%PORT_8080%%;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /modsec-disabled {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine Off
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /nobodyaccess {
|
||||
modsecurity_rules '
|
||||
SecRequestBodyAccess Off
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /bodylimitprocesspartial {
|
||||
modsecurity_rules '
|
||||
SecRequestBodyLimitAction ProcessPartial
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /bodylimitincreased {
|
||||
modsecurity_rules '
|
||||
SecRequestBodyLimit 512
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /server {
|
||||
modsecurity off;
|
||||
|
||||
location /server/modsec-disabled {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8082%%;
|
||||
}
|
||||
|
||||
location /server/nobodyaccess {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8083%%;
|
||||
}
|
||||
|
||||
location /server/bodylimitprocesspartial {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8084%%;
|
||||
}
|
||||
|
||||
location /server/bodylimitincreased {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8085%%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:%%PORT_8082%%;
|
||||
|
||||
modsecurity_rules '
|
||||
SecRuleEngine Off
|
||||
';
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:%%PORT_8083%%;
|
||||
|
||||
modsecurity_rules '
|
||||
SecRequestBodyAccess Off
|
||||
';
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:%%PORT_8084%%;
|
||||
|
||||
modsecurity_rules '
|
||||
SecRequestBodyLimitAction ProcessPartial
|
||||
';
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:%%PORT_8085%%;
|
||||
|
||||
modsecurity_rules '
|
||||
SecRequestBodyLimit 512
|
||||
';
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->run_daemon(\&http_daemon);
|
||||
$t->run()->waitforsocket('127.0.0.1:' . port(8081));
|
||||
|
||||
$t->plan(10);
|
||||
|
||||
###############################################################################
|
||||
|
||||
like(http_get_body('/', 'GOOD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "http level defaults, pass");
|
||||
like(http_get_body('/', 'VERY BAD BODY'), qr/^HTTP.*403/, "http level defaults, block");
|
||||
|
||||
like(http_get_body('/modsec-disabled', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRuleEngine, pass");
|
||||
like(http_get_body('/nobodyaccess', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRequestBodyAccess, pass");
|
||||
like(http_get_body('/bodylimitprocesspartial', 'BODY' x 33), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRequestBodyLimitAction, pass");
|
||||
like(http_get_body('/bodylimitincreased', 'BODY' x 64), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRequestBodyLimit, pass");
|
||||
|
||||
like(http_get_body('/server/modsec-disabled', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRuleEngine, pass");
|
||||
like(http_get_body('/server/nobodyaccess', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRequestBodyAccess, pass");
|
||||
like(http_get_body('/server/bodylimitprocesspartial', 'BODY' x 33), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRequestBodyLimitAction, pass");
|
||||
like(http_get_body('/server/bodylimitincreased', 'BODY' x 64), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRequestBodyLimit, pass");
|
||||
|
||||
###############################################################################
|
||||
|
||||
sub http_daemon {
|
||||
my $server = IO::Socket::INET->new(
|
||||
Proto => 'tcp',
|
||||
LocalHost => '127.0.0.1:' . port(8081),
|
||||
Listen => 5,
|
||||
Reuse => 1
|
||||
)
|
||||
or die "Can't create listening socket: $!\n";
|
||||
|
||||
local $SIG{PIPE} = 'IGNORE';
|
||||
|
||||
while (my $client = $server->accept()) {
|
||||
$client->autoflush(1);
|
||||
|
||||
my $headers = '';
|
||||
my $uri = '';
|
||||
|
||||
while (<$client>) {
|
||||
$headers .= $_;
|
||||
last if (/^\x0d?\x0a?$/);
|
||||
}
|
||||
|
||||
$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
|
||||
|
||||
print $client <<'EOF';
|
||||
HTTP/1.1 200 OK
|
||||
Connection: close
|
||||
|
||||
EOF
|
||||
print $client "TEST-OK-IF-YOU-SEE-THIS"
|
||||
unless $headers =~ /^HEAD/i;
|
||||
|
||||
close $client;
|
||||
}
|
||||
}
|
||||
|
||||
sub http_get_body {
|
||||
my $uri = shift;
|
||||
my $last = pop;
|
||||
return http( join '', (map {
|
||||
my $body = $_;
|
||||
"GET $uri HTTP/1.1" . CRLF
|
||||
. "Host: localhost" . CRLF
|
||||
. "Content-Length: " . (length $body) . CRLF . CRLF
|
||||
. $body
|
||||
} @_),
|
||||
"GET $uri HTTP/1.1" . CRLF
|
||||
. "Host: localhost" . CRLF
|
||||
. "Connection: close" . CRLF
|
||||
. "Content-Length: " . (length $last) . CRLF . CRLF
|
||||
. $last
|
||||
);
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,112 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# ModSecurity, http://www.modsecurity.org/
|
||||
# Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
#
|
||||
# You may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# If any of the files related to licensing are missing or if you have any
|
||||
# other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
# directly using the email address security@modsecurity.org.
|
||||
#
|
||||
|
||||
|
||||
# Tests for ModSecurity module.
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq whee" "id:10,phase:2"
|
||||
SecRule ARGS "@streq whee" "id:11,phase:2"
|
||||
';
|
||||
|
||||
location / {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq root" "id:21,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
';
|
||||
}
|
||||
|
||||
location /subfolder1 {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq subfolder1" "id:31,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
';
|
||||
location /subfolder1/subfolder2 {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq subfolder2" "id:41,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder1');
|
||||
$t->write_file("/subfolder1/index.html", "should be moved/blocked before this.");
|
||||
mkdir($t->testdir() . '/subfolder1/subfolder2');
|
||||
$t->write_file("/subfolder1/subfolder2/index.html", "should be moved/blocked before this.");
|
||||
|
||||
$t->run();
|
||||
$t->plan(9);
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
# Performing requests at root
|
||||
like(http_get('/index.html?what=root'), qr/^HTTP.*302/, 'redirect 302 - root');
|
||||
like(http_get('/index.html?what=subfolder1'), qr/should be moved\/blocked before this./, 'nothing - requested subfolder1 at root');
|
||||
like(http_get('/index.html?what=subfolder2'), qr/should be moved\/blocked before this./, 'nothing - requested subfolder2 at root');
|
||||
|
||||
# Performing requests at subfolder1
|
||||
like(http_get('/subfolder1/index.html?what=root'), qr/should be moved\/blocked before this./, 'nothing - requested root at subfolder 1');
|
||||
like(http_get('/subfolder1/index.html?what=subfolder1'), qr/^HTTP.*302/, 'redirect 302 - subfolder 1');
|
||||
like(http_get('/subfolder1/index.html?what=subfolder2'), qr/should be moved\/blocked before this./, 'nothing - requested subfolder2 at subfolder1');
|
||||
|
||||
# Performing requests at subfolder2
|
||||
like(http_get('/subfolder1/subfolder2/index.html?what=root'), qr/should be moved\/blocked before this./, 'nothing - requested root at subfolder 2');
|
||||
like(http_get('/subfolder1/subfolder2/index.html?what=subfolder1'), qr/^HTTP.*302/, 'redirect 302 - subfolder 2');
|
||||
like(http_get('/subfolder1/subfolder2/index.html?what=subfolder2'), qr/^HTTP.*302/, 'redirect 302 - subfolder 2');
|
||||
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity module (HTTP/2).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
use Test::Nginx::HTTP2;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http http_v2/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080 http2;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq whee" "id:10,phase:2"
|
||||
SecRule ARGS "@streq whee" "id:11,phase:2"
|
||||
';
|
||||
}
|
||||
location /phase1 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:1,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:1,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
location /phase2 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:2,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:2,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:2,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:2,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:2,status:403,block"
|
||||
';
|
||||
}
|
||||
location /phase3 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:3,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:3,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:3,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:3,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:3,status:403,block"
|
||||
';
|
||||
}
|
||||
location /phase4 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecResponseBodyAccess On
|
||||
SecDefaultAction "phase:4,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:4,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:4,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:4,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:4,status:403,block"
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/phase1", "should be moved/blocked before this.");
|
||||
$t->write_file("/phase2", "should be moved/blocked before this.");
|
||||
$t->write_file("/phase3", "should be moved/blocked before this.");
|
||||
$t->write_file("/phase4", "should not be moved/blocked, headers delivered before phase 4.");
|
||||
$t->run();
|
||||
$t->plan(20);
|
||||
|
||||
###############################################################################
|
||||
|
||||
my ($phase, $s, $sid, $frames, $frame);
|
||||
|
||||
# Redirect (302)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=redirect302" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 302, "redirect 302 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=redirect302' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'redirect 302 - phase 4');
|
||||
}
|
||||
|
||||
# Redirect (301)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=redirect301" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 301, "redirect 301 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=redirect301' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'redirect 301 - phase 4');
|
||||
}
|
||||
|
||||
# Block (401)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=block401" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 401, "block 401 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=block401' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'block 401 - phase 4');
|
||||
}
|
||||
|
||||
# Block (403)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=block403" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 403, "block 403 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=block403' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'block 403 - phase 4');
|
||||
}
|
||||
|
||||
# Nothing to detect
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=nothing" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame->{data}, "should be moved\/blocked before this.", "nothing phase ${phase}");
|
||||
}
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase4?what=nothing" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame->{data}, "should not be moved\/blocked, headers delivered before phase 4.", 'nothing phase 4');
|
|
@ -1,287 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity over the http proxy module (HTTP/2).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
use Test::Nginx::HTTP2;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http http_v2 proxy/)->plan(23);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080 http2;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
|
||||
location /phase1 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:1,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:1,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
location /phase2 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:2,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:2,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:2,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:2,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:2,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
location /phase3 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:3,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:3,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:3,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:3,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:3,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
location /phase4 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecResponseBodyAccess On
|
||||
SecDefaultAction "phase:4,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:4,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:4,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:4,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:4,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
$t->run_daemon(\&http_daemon);
|
||||
$t->run()->waitforsocket('127.0.0.1:' . port(8081));
|
||||
|
||||
###############################################################################
|
||||
|
||||
my ($phase, $s, $sid, $frames, $frame);
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/SEE-THIS/, "proxy request");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/multi' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/AND-THIS/, "proxy request with multiple packets");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/', method => 'HEAD' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
unlike($frame->{data}, qr/SEE-THIS/, "proxy head request");
|
||||
|
||||
# Redirect (302)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=redirect302" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 302, "redirect 302 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=redirect302' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'redirect 302 - phase 4');
|
||||
}
|
||||
|
||||
# Redirect (301)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=redirect301" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 301, "redirect 301 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=redirect301' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'redirect 301 - phase 4');
|
||||
}
|
||||
|
||||
# Block (401)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=block401" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 401, "block 401 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=block401' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'block 401 - phase 4');
|
||||
}
|
||||
|
||||
|
||||
# Block (403)
|
||||
|
||||
for $phase (1 .. 3) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=block403" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 403, "block 403 - phase ${phase}");
|
||||
}
|
||||
|
||||
SKIP: {
|
||||
skip 'long test', 1 unless $ENV{TEST_NGINX_UNSAFE};
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => '/phase4?what=block403' });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
is($frame, undef, 'block 403 - phase 4');
|
||||
}
|
||||
|
||||
# Nothing to detect
|
||||
#like(http_get('/phase1?what=nothing'), qr/phase1\?what=nothing\' not found/, 'nothing phase 1');
|
||||
#like(http_get('/phase2?what=nothing'), qr/phase2\?what=nothing\' not found/, 'nothing phase 2');
|
||||
#like(http_get('/phase3?what=nothing'), qr/phase3\?what=nothing\' not found/, 'nothing phase 3');
|
||||
#like(http_get('/phase4?what=nothing'), qr/phase4\?what=nothing\' not found/, 'nothing phase 4');
|
||||
|
||||
for $phase (1 .. 4) {
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ path => "/phase${phase}?what=nothing" });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/phase${phase}\?what=nothing\' not found/, "nothing phase ${phase}");
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
sub http_daemon {
|
||||
my $server = IO::Socket::INET->new(
|
||||
Proto => 'tcp',
|
||||
LocalHost => '127.0.0.1:' . port(8081),
|
||||
Listen => 5,
|
||||
Reuse => 1
|
||||
)
|
||||
or die "Can't create listening socket: $!\n";
|
||||
|
||||
local $SIG{PIPE} = 'IGNORE';
|
||||
|
||||
while (my $client = $server->accept()) {
|
||||
$client->autoflush(1);
|
||||
|
||||
my $headers = '';
|
||||
my $uri = '';
|
||||
|
||||
while (<$client>) {
|
||||
$headers .= $_;
|
||||
last if (/^\x0d?\x0a?$/);
|
||||
}
|
||||
|
||||
$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
|
||||
|
||||
if ($uri eq '/') {
|
||||
print $client <<'EOF';
|
||||
HTTP/1.1 200 OK
|
||||
Connection: close
|
||||
|
||||
EOF
|
||||
print $client "TEST-OK-IF-YOU-SEE-THIS"
|
||||
unless $headers =~ /^HEAD/i;
|
||||
|
||||
} elsif ($uri eq '/multi') {
|
||||
|
||||
print $client <<"EOF";
|
||||
HTTP/1.1 200 OK
|
||||
Connection: close
|
||||
|
||||
TEST-OK-IF-YOU-SEE-THIS
|
||||
EOF
|
||||
|
||||
select undef, undef, undef, 0.1;
|
||||
print $client 'AND-THIS';
|
||||
|
||||
} else {
|
||||
|
||||
print $client <<"EOF";
|
||||
HTTP/1.1 404 Not Found
|
||||
Connection: close
|
||||
|
||||
Oops, '$uri' not found
|
||||
EOF
|
||||
}
|
||||
|
||||
close $client;
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,208 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
|
||||
# Tests for ModSecurity over the http proxy module.
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(23);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
|
||||
location /phase1 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:1,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:1,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
location /phase2 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:2,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:2,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:2,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:2,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:2,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
location /phase3 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:3,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:3,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:3,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:3,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:3,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
location /phase4 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecResponseBodyAccess On
|
||||
SecDefaultAction "phase:4,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:4,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:4,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:4,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:4,status:403,block"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
proxy_read_timeout 1s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
$t->todo_alerts();
|
||||
$t->run_daemon(\&http_daemon);
|
||||
$t->run()->waitforsocket('127.0.0.1:' . port(8081));
|
||||
|
||||
###############################################################################
|
||||
|
||||
like(http_get('/'), qr/SEE-THIS/, 'proxy request');
|
||||
like(http_get('/multi'), qr/AND-THIS/, 'proxy request with multiple packets');
|
||||
|
||||
unlike(http_head('/'), qr/SEE-THIS/, 'proxy head request');
|
||||
|
||||
|
||||
# Redirect (302)
|
||||
like(http_get('/phase1?what=redirect302'), qr/^HTTP.*302/, 'redirect 302 - phase 1');
|
||||
like(http_get('/phase2?what=redirect302'), qr/^HTTP.*302/, 'redirect 302 - phase 2');
|
||||
like(http_get('/phase3?what=redirect302'), qr/^HTTP.*302/, 'redirect 302 - phase 3');
|
||||
is(http_get('/phase4?what=redirect302'), '', 'redirect 302 - phase 4');
|
||||
|
||||
# Redirect (301)
|
||||
like(http_get('/phase1?what=redirect301'), qr/^HTTP.*301/, 'redirect 301 - phase 1');
|
||||
like(http_get('/phase2?what=redirect301'), qr/^HTTP.*301/, 'redirect 301 - phase 2');
|
||||
like(http_get('/phase3?what=redirect301'), qr/^HTTP.*301/, 'redirect 301 - phase 3');
|
||||
is(http_get('/phase4?what=redirect301'), '', 'redirect 301 - phase 4');
|
||||
|
||||
# Block (401)
|
||||
like(http_get('/phase1?what=block401'), qr/^HTTP.*401/, 'block 401 - phase 1');
|
||||
like(http_get('/phase2?what=block401'), qr/^HTTP.*401/, 'block 401 - phase 2');
|
||||
like(http_get('/phase3?what=block401'), qr/^HTTP.*401/, 'block 401 - phase 3');
|
||||
is(http_get('/phase4?what=block401'), '', 'block 401 - phase 4');
|
||||
|
||||
# Block (403)
|
||||
like(http_get('/phase1?what=block403'), qr/^HTTP.*403/, 'block 403 - phase 1');
|
||||
like(http_get('/phase2?what=block403'), qr/^HTTP.*403/, 'block 403 - phase 2');
|
||||
like(http_get('/phase3?what=block403'), qr/^HTTP.*403/, 'block 403 - phase 3');
|
||||
is(http_get('/phase4?what=block403'), '', 'block 403 - phase 4');
|
||||
|
||||
# Nothing to detect
|
||||
like(http_get('/phase1?what=nothing'), qr/phase1\?what=nothing\' not found/, 'nothing phase 1');
|
||||
like(http_get('/phase2?what=nothing'), qr/phase2\?what=nothing\' not found/, 'nothing phase 2');
|
||||
like(http_get('/phase3?what=nothing'), qr/phase3\?what=nothing\' not found/, 'nothing phase 3');
|
||||
like(http_get('/phase4?what=nothing'), qr/phase4\?what=nothing\' not found/, 'nothing phase 4');
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
sub http_daemon {
|
||||
my $server = IO::Socket::INET->new(
|
||||
Proto => 'tcp',
|
||||
LocalHost => '127.0.0.1:' . port(8081),
|
||||
Listen => 5,
|
||||
Reuse => 1
|
||||
)
|
||||
or die "Can't create listening socket: $!\n";
|
||||
|
||||
local $SIG{PIPE} = 'IGNORE';
|
||||
|
||||
while (my $client = $server->accept()) {
|
||||
$client->autoflush(1);
|
||||
|
||||
my $headers = '';
|
||||
my $uri = '';
|
||||
|
||||
while (<$client>) {
|
||||
$headers .= $_;
|
||||
last if (/^\x0d?\x0a?$/);
|
||||
}
|
||||
|
||||
$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
|
||||
|
||||
if ($uri eq '/') {
|
||||
print $client <<'EOF';
|
||||
HTTP/1.1 200 OK
|
||||
Connection: close
|
||||
|
||||
EOF
|
||||
print $client "TEST-OK-IF-YOU-SEE-THIS"
|
||||
unless $headers =~ /^HEAD/i;
|
||||
|
||||
} elsif ($uri eq '/multi') {
|
||||
|
||||
print $client <<"EOF";
|
||||
HTTP/1.1 200 OK
|
||||
Connection: close
|
||||
|
||||
TEST-OK-IF-YOU-SEE-THIS
|
||||
EOF
|
||||
|
||||
select undef, undef, undef, 0.1;
|
||||
print $client 'AND-THIS';
|
||||
|
||||
} else {
|
||||
|
||||
print $client <<"EOF";
|
||||
HTTP/1.1 404 Not Found
|
||||
Connection: close
|
||||
|
||||
Oops, '$uri' not found
|
||||
EOF
|
||||
}
|
||||
|
||||
close $client;
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,224 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity-nginx connector (request body operations, HTTP/2).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
use Socket qw/ CRLF /;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
use Test::Nginx::HTTP2;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http http_v2 proxy auth_request/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8081;
|
||||
location / {
|
||||
return 200 "TEST-OK-IF-YOU-SEE-THIS";
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080 http2;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
client_header_buffer_size 1024;
|
||||
|
||||
location /bodyaccess {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:11,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
|
||||
location /nobodyaccess {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess Off
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:21,phase:request,deny,log,status:403"
|
||||
SecRule ARGS_POST|ARGS_POST_NAMES "@rx BAD ARG" "id:22,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
|
||||
location /bodylimitreject {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRequestBodyLimit 128
|
||||
SecRequestBodyLimitAction Reject
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:31,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
|
||||
location /bodylimitprocesspartial {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRequestBodyLimit 128
|
||||
SecRequestBodyLimitAction ProcessPartial
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:41,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
|
||||
location = /auth {
|
||||
return 200;
|
||||
}
|
||||
|
||||
location = /useauth {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
';
|
||||
auth_request /auth;
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->run();
|
||||
|
||||
$t->plan(36);
|
||||
|
||||
###############################################################################
|
||||
|
||||
my ($s, $sid, $frames, $frame);
|
||||
|
||||
foreach my $method (('GET', 'POST', 'PUT', 'DELETE')) {
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/bodyaccess', 'body_more' => 1 });
|
||||
$s->h2_body('GOOD BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "${method} request body access on, pass");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/bodyaccess', 'body_more' => 1 });
|
||||
$s->h2_body('VERY BAD BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 403, "${method} request body access on, block");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/nobodyaccess', 'body_more' => 1 });
|
||||
$s->h2_body('VERY BAD BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "${method} request body access off, pass");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ 'body_more' => 1,
|
||||
headers => [
|
||||
{name => ':method', value => "${method}" },
|
||||
{name => ':scheme', value => 'http' },
|
||||
{name => ':path', value => '/nobodyaccess' },
|
||||
{name => 'host', value => 'localhost' },
|
||||
{name => 'content-type', value => 'application/x-www-form-urlencoded' }
|
||||
] });
|
||||
$s->h2_body('test=VERY BAD BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "${method} request body access off (ARGS_POST), pass");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/bodylimitreject', 'body_more' => 1 });
|
||||
$s->h2_body('BODY' x 32);
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "${method} request body limit reject, pass");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/bodylimitreject', 'body_more' => 1 });
|
||||
$s->h2_body('BODY' x 33);
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 403, "${method} request body limit reject, block");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/bodylimitprocesspartial', 'body_more' => 1 });
|
||||
$s->h2_body('BODY' x 32 . 'BAD BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "${method} request body limit process partial, pass");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => $method, path => '/bodylimitprocesspartial', 'body_more' => 1 });
|
||||
$s->h2_body('BODY' x 30 . 'BAD BODY' x 32);
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
|
||||
is($frame->{headers}->{':status'}, 403, "${method} request body limit process partial, block");
|
||||
|
||||
}
|
||||
|
||||
TODO: {
|
||||
# https://github.com/SpiderLabs/ModSecurity-nginx/issues/163
|
||||
# https://github.com/nginx/nginx/commit/6c89d752c8ab3a3cc0832927484808b68153f8c4
|
||||
local $TODO = 'not yet' unless $t->has_version('1.19.3');
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => 'POST', path => '/useauth', 'body' => 'BODY' x 16 });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "POST with auth_request (request size < client_header_buffer_size)");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => 'POST', path => '/useauth', 'body' => 'BODY' x 257 });
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "POST with auth_request (request size > client_header_buffer_size)");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => 'POST', path => '/useauth', 'body_more' => 1 });
|
||||
$s->h2_body('BODY' x 15, { 'body_more' => 1 });
|
||||
select undef, undef, undef, 0.1;
|
||||
$s->h2_body('BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "POST with auth_request (request size < client_header_buffer_size), no preread");
|
||||
|
||||
$s = Test::Nginx::HTTP2->new();
|
||||
$sid = $s->new_stream({ method => 'POST', path => '/useauth', 'body_more' => 1 });
|
||||
$s->h2_body('BODY' x 256, { 'body_more' => 1 });
|
||||
select undef, undef, undef, 0.1;
|
||||
$s->h2_body('BODY');
|
||||
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
|
||||
($frame) = grep { $_->{type} eq "DATA" } @$frames;
|
||||
like($frame->{data}, qr/TEST-OK-IF-YOU-SEE-THIS/, "POST with auth_request (request size > client_header_buffer_size), no preread");
|
||||
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,251 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity-nginx connector (request body operations).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
use Socket qw/ CRLF /;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http proxy auth_request/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
client_header_buffer_size 1024;
|
||||
|
||||
location /bodyaccess {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:11,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /nobodyaccess {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess Off
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:21,phase:request,deny,log,status:403"
|
||||
SecRule ARGS_POST|ARGS_POST_NAMES "@rx BAD ARG" "id:22,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /bodylimitreject {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRequestBodyLimit 128
|
||||
SecRequestBodyLimitAction Reject
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:31,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location /bodylimitrejectserver {
|
||||
modsecurity off;
|
||||
proxy_pass http://127.0.0.1:%%PORT_8082%%;
|
||||
}
|
||||
|
||||
location /bodylimitprocesspartial {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRequestBodyLimit 128
|
||||
SecRequestBodyLimitAction ProcessPartial
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:41,phase:request,deny,log,status:403"
|
||||
';
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
|
||||
location = /auth {
|
||||
return 200;
|
||||
}
|
||||
|
||||
location = /useauth {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
';
|
||||
auth_request /auth;
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:%%PORT_8082%%;
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecRequestBodyLimit 128
|
||||
SecRequestBodyLimitAction Reject
|
||||
SecRule REQUEST_BODY "@rx BAD BODY" "id:31,phase:request,deny,log,status:403"
|
||||
';
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:%%PORT_8081%%;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->run_daemon(\&http_daemon);
|
||||
$t->run()->waitforsocket('127.0.0.1:' . port(8081));
|
||||
|
||||
$t->plan(40);
|
||||
|
||||
###############################################################################
|
||||
|
||||
foreach my $method (('GET', 'POST', 'PUT', 'DELETE')) {
|
||||
like(http_req_body($method, '/bodyaccess', 'GOOD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "$method request body access on, pass");
|
||||
like(http_req_body($method, '/bodyaccess', 'VERY BAD BODY'), qr/^HTTP.*403/, "$method request body access on, block");
|
||||
like(http_req_body($method, '/nobodyaccess', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "$method request body access off, pass");
|
||||
like(http_req_body_postargs($method, '/nobodyaccess', 'BAD ARG'), qr/TEST-OK-IF-YOU-SEE-THIS/, "$method request body access off (ARGS_POST), pass");
|
||||
like(http_req_body($method, '/bodylimitreject', 'BODY' x 32), qr/TEST-OK-IF-YOU-SEE-THIS/, "$method request body limit reject, pass");
|
||||
like(http_req_body($method, '/bodylimitreject', 'BODY' x 33), qr/^HTTP.*403/, "$method request body limit reject, block");
|
||||
like(http_req_body($method, '/bodylimitprocesspartial', 'BODY' x 32 . 'BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "$method request body limit process partial, pass");
|
||||
like(http_req_body($method, '/bodylimitprocesspartial', 'BODY' x 30 . 'BAD BODY' x 32), qr/^HTTP.*403/, "$method request body limit process partial, block");
|
||||
}
|
||||
|
||||
like(http_req_body('POST', '/useauth', 'BODY' x 16), qr/TEST-OK-IF-YOU-SEE-THIS/, "POST with auth_request (request size < client_header_buffer_size)");
|
||||
like(http_req_body('POST', '/useauth', 'BODY' x 257), qr/TEST-OK-IF-YOU-SEE-THIS/, "POST with auth_request (request size > client_header_buffer_size)");
|
||||
|
||||
like(
|
||||
http(
|
||||
'POST /useauth HTTP/1.0' . CRLF
|
||||
. 'Content-Length: 1028' . CRLF . CRLF
|
||||
. 'BODY' x 256,
|
||||
sleep => 0.1,
|
||||
body => 'BODY'
|
||||
),
|
||||
qr/TEST-OK-IF-YOU-SEE-THIS/,
|
||||
'POST with auth_request (request size > client_header_buffer_size), no preread'
|
||||
);
|
||||
|
||||
like(
|
||||
http(
|
||||
'POST /useauth HTTP/1.0' . CRLF
|
||||
. 'Content-Length: 64' . CRLF . CRLF
|
||||
. 'BODY' x 15,
|
||||
sleep => 0.1,
|
||||
body => 'BODY'
|
||||
),
|
||||
qr/TEST-OK-IF-YOU-SEE-THIS/,
|
||||
'POST with auth_request (request size < client_header_buffer_size), no preread'
|
||||
);
|
||||
|
||||
foreach my $method (('GET', 'POST', 'PUT', 'DELETE')) {
|
||||
like(http_req_body($method, '/bodylimitrejectserver', 'BODY' x 33), qr/^HTTP.*403/, "$method request body limit reject, block (inherited SecRequestBodyLimit)");
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
sub http_daemon {
|
||||
my $server = IO::Socket::INET->new(
|
||||
Proto => 'tcp',
|
||||
LocalHost => '127.0.0.1:' . port(8081),
|
||||
Listen => 5,
|
||||
Reuse => 1
|
||||
)
|
||||
or die "Can't create listening socket: $!\n";
|
||||
|
||||
local $SIG{PIPE} = 'IGNORE';
|
||||
|
||||
while (my $client = $server->accept()) {
|
||||
$client->autoflush(1);
|
||||
|
||||
my $headers = '';
|
||||
my $uri = '';
|
||||
|
||||
while (<$client>) {
|
||||
$headers .= $_;
|
||||
last if (/^\x0d?\x0a?$/);
|
||||
}
|
||||
|
||||
$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
|
||||
|
||||
print $client <<'EOF';
|
||||
HTTP/1.1 200 OK
|
||||
Connection: close
|
||||
|
||||
EOF
|
||||
print $client "TEST-OK-IF-YOU-SEE-THIS"
|
||||
unless $headers =~ /^HEAD/i;
|
||||
|
||||
close $client;
|
||||
}
|
||||
}
|
||||
|
||||
sub http_req_body {
|
||||
my $method = shift;
|
||||
my $uri = shift;
|
||||
my $last = pop;
|
||||
return http( join '', (map {
|
||||
my $body = $_;
|
||||
"$method $uri HTTP/1.1" . CRLF
|
||||
. "Host: localhost" . CRLF
|
||||
. "Content-Length: " . (length $body) . CRLF . CRLF
|
||||
. $body
|
||||
} @_),
|
||||
"$method $uri HTTP/1.1" . CRLF
|
||||
. "Host: localhost" . CRLF
|
||||
. "Connection: close" . CRLF
|
||||
. "Content-Length: " . (length $last) . CRLF . CRLF
|
||||
. $last
|
||||
);
|
||||
}
|
||||
|
||||
sub http_req_body_postargs {
|
||||
my $method = shift;
|
||||
my $uri = shift;
|
||||
my $last = pop;
|
||||
return http( join '', (map {
|
||||
my $body = $_;
|
||||
"$method $uri HTTP/1.1" . CRLF
|
||||
. "Host: localhost" . CRLF
|
||||
. "Content-Type: application/x-www-form-urlencoded" . CRLF
|
||||
. "Content-Length: " . (length "test=" . $body) . CRLF . CRLF
|
||||
. "test=" . $body
|
||||
} @_),
|
||||
"$method $uri HTTP/1.1" . CRLF
|
||||
. "Host: localhost" . CRLF
|
||||
. "Connection: close" . CRLF
|
||||
. "Content-Type: application/x-www-form-urlencoded" . CRLF
|
||||
. "Content-Length: " . (length "test=" . $last) . CRLF . CRLF
|
||||
. "test=" . $last
|
||||
);
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,69 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity-nginx connector (response body operations).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
|
||||
location /body1 {
|
||||
default_type text/plain;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecResponseBodyAccess On
|
||||
SecResponseBodyLimit 128
|
||||
SecRule RESPONSE_BODY "@rx BAD BODY" "id:11,phase:response,deny,log,status:403"
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/body1", "BAD BODY");
|
||||
$t->run();
|
||||
$t->todo_alerts();
|
||||
$t->plan(1);
|
||||
|
||||
###############################################################################
|
||||
|
||||
TODO: {
|
||||
local $TODO = 'not yet';
|
||||
|
||||
like(http_get('/body1'), qr/^HTTP.*403/, 'response body (block)');
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity-nginx connector (scoring).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
modsecurity on;
|
||||
|
||||
location /absolute {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq badarg1" "id:11,phase:2,setvar:tx.score=1"
|
||||
SecRule ARGS "@streq badarg2" "id:12,phase:2,setvar:tx.score=2"
|
||||
SecRule TX:SCORE "@ge 2" "id:199,phase:request,deny,log,status:403"
|
||||
';
|
||||
}
|
||||
|
||||
location /iterative {
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq badarg1" "id:21,phase:2,setvar:tx.score=+1"
|
||||
SecRule ARGS "@streq badarg2" "id:22,phase:2,setvar:tx.score=+1"
|
||||
SecRule ARGS "@streq badarg3" "id:23,phase:2,setvar:tx.score=+1"
|
||||
SecRule TX:SCORE "@ge 3" "id:299,phase:request,deny,log,status:403"
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/absolute", "should be moved/blocked before this.");
|
||||
$t->write_file("/iterative", "should be moved/blocked before this.");
|
||||
$t->run();
|
||||
$t->plan(5);
|
||||
|
||||
###############################################################################
|
||||
|
||||
like(http_get('/absolute?what=badarg1'), qr/should be moved\/blocked before this./, 'absolute scoring 1 (pass)');
|
||||
like(http_get('/absolute?what=badarg2'), qr/^HTTP.*403/, 'absolute scoring 2 (block)');
|
||||
|
||||
like(http_get('/iterative?arg1=badarg1'), qr/should be moved\/blocked before this./, 'iterative scoring 1 (pass)');
|
||||
like(http_get('/iterative?arg1=badarg1&arg2=badarg2'), qr/should be moved\/blocked before this./, 'iterative scoring 2 (pass)');
|
||||
like(http_get('/iterative?arg1=badarg1&arg2=badarg2&arg3=badarg3'), qr/^HTTP.*403/, 'iterative scoring 3 (block)');
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# (C) Andrei Belov
|
||||
|
||||
# Tests for ModSecurity-nginx connector (modsecurity_transaction_id).
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->plan(5)->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
modsecurity_transaction_id "tid-HTTP-DEFAULT-$request_id";
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name server1;
|
||||
|
||||
location / {
|
||||
error_log %%TESTDIR%%/e_s1l1.log info;
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name server2;
|
||||
|
||||
modsecurity_transaction_id "tid-SERVER-DEFAULT-$request_id";
|
||||
|
||||
location / {
|
||||
error_log %%TESTDIR%%/e_s2l1.log info;
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
|
||||
location /specific {
|
||||
error_log %%TESTDIR%%/e_s2l2.log info;
|
||||
modsecurity on;
|
||||
modsecurity_transaction_id "tid-LOCATION-SPECIFIC-$request_id";
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
|
||||
location /debuglog {
|
||||
modsecurity on;
|
||||
modsecurity_transaction_id "tid-DEBUG-$request_id";
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDebugLog %%TESTDIR%%/modsec_debug.log
|
||||
SecDebugLogLevel 4
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
|
||||
location /auditlog {
|
||||
modsecurity on;
|
||||
modsecurity_transaction_id "tid-AUDIT-$request_id";
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecAuditEngine On
|
||||
SecAuditLogParts A
|
||||
SecAuditLog %%TESTDIR%%/modsec_audit.log
|
||||
SecAuditLogType Serial
|
||||
SecAuditLogStorageDir %%TESTDIR%%/
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->run();
|
||||
|
||||
###############################################################################
|
||||
|
||||
# charge limit_req
|
||||
|
||||
http(<<EOF);
|
||||
GET /?what=block403 HTTP/1.0
|
||||
Host: server1
|
||||
|
||||
EOF
|
||||
|
||||
isnt(lines($t, 'e_s1l1.log', 'unique_id "tid-HTTP-DEFAULT-'), 0, 'http default');
|
||||
|
||||
http(<<EOF);
|
||||
GET /?what=block403 HTTP/1.0
|
||||
Host: server2
|
||||
|
||||
EOF
|
||||
|
||||
isnt(lines($t, 'e_s2l1.log', 'unique_id "tid-SERVER-DEFAULT-'), 0, 'server default');
|
||||
|
||||
http(<<EOF);
|
||||
GET /specific/?what=block403 HTTP/1.0
|
||||
Host: server2
|
||||
|
||||
EOF
|
||||
|
||||
isnt(lines($t, 'e_s2l2.log', 'unique_id "tid-LOCATION-SPECIFIC-'), 0, 'location specific');
|
||||
|
||||
http(<<EOF);
|
||||
GET /debuglog/?what=block403 HTTP/1.0
|
||||
Host: server2
|
||||
|
||||
EOF
|
||||
|
||||
isnt(lines($t, 'modsec_debug.log', 'tid-DEBUG-'), 0, 'libmodsecurity debug log');
|
||||
|
||||
http(<<EOF);
|
||||
GET /auditlog/?what=block403 HTTP/1.0
|
||||
Host: server2
|
||||
|
||||
EOF
|
||||
|
||||
isnt(lines($t, 'modsec_audit.log', 'tid-AUDIT-'), 0, 'libmodsecurity audit log');
|
||||
|
||||
###############################################################################
|
||||
|
||||
sub lines {
|
||||
my ($t, $file, $pattern) = @_;
|
||||
my $path = $t->testdir() . '/' . $file;
|
||||
open my $fh, '<', $path or return "$!";
|
||||
my $value = map { $_ =~ /\Q$pattern\E/ } (<$fh>);
|
||||
close $fh;
|
||||
return $value;
|
||||
}
|
||||
|
||||
###############################################################################
|
|
@ -1,172 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# ModSecurity, http://www.modsecurity.org/
|
||||
# Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
#
|
||||
# You may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# If any of the files related to licensing are missing or if you have any
|
||||
# other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
# directly using the email address security@modsecurity.org.
|
||||
#
|
||||
|
||||
|
||||
# Tests for ModSecurity module.
|
||||
|
||||
###############################################################################
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Test::More;
|
||||
|
||||
BEGIN { use FindBin; chdir($FindBin::Bin); }
|
||||
|
||||
use lib 'lib';
|
||||
use Test::Nginx;
|
||||
|
||||
###############################################################################
|
||||
|
||||
select STDERR; $| = 1;
|
||||
select STDOUT; $| = 1;
|
||||
|
||||
my $t = Test::Nginx->new()->has(qw/http/);
|
||||
|
||||
$t->write_file_expand('nginx.conf', <<'EOF');
|
||||
|
||||
%%TEST_GLOBALS%%
|
||||
|
||||
daemon off;
|
||||
|
||||
events {
|
||||
}
|
||||
|
||||
http {
|
||||
%%TEST_GLOBALS_HTTP%%
|
||||
|
||||
server {
|
||||
listen 127.0.0.1:8080;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecRule ARGS "@streq whee" "id:10,phase:2"
|
||||
SecRule ARGS "@streq whee" "id:11,phase:2"
|
||||
';
|
||||
}
|
||||
location /phase1 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:1,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:1,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:1,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:1,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:1,status:403,block"
|
||||
';
|
||||
}
|
||||
location /phase2 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:2,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:2,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:2,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:2,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:2,status:403,block"
|
||||
';
|
||||
}
|
||||
location /phase3 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDefaultAction "phase:3,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:3,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:3,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:3,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:3,status:403,block"
|
||||
';
|
||||
}
|
||||
location /phase4 {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecResponseBodyAccess On
|
||||
SecDefaultAction "phase:4,log,deny,status:403"
|
||||
SecRule ARGS "@streq redirect301" "id:1,phase:4,status:301,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq redirect302" "id:2,phase:4,status:302,redirect:http://www.modsecurity.org"
|
||||
SecRule ARGS "@streq block401" "id:3,phase:4,status:401,block"
|
||||
SecRule ARGS "@streq block403" "id:4,phase:4,status:403,block"
|
||||
';
|
||||
}
|
||||
location /early-block {
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecResponseBodyAccess On
|
||||
SecDefaultAction "phase:1,log,auditlog,pass"
|
||||
SecDefaultAction "phase:2,log,auditlog,pass"
|
||||
SecAction "id:900101,phase:1,nolog,pass,t:none,setvar:tx.trigger_phase1=1"
|
||||
SecAction "id:900103,phase:1,nolog,pass,t:none,setvar:tx.trigger_phase3=1"
|
||||
SecAction "id:900105,phase:1,nolog,pass,t:none,setvar:tx.trigger_phase5=1"
|
||||
SecRule TX:TRIGGER_PHASE1 "@eq 1" "id:901111,phase:1,t:none,deny,log"
|
||||
SecRule REQUEST_BODY "@rx attack" "id:901121,phase:2,t:none,deny,log"
|
||||
SecRule TX:TRIGGER_PHASE3 "@eq 1" "id:901131,phase:3,t:none,deny,log"
|
||||
SecRule RESPONSE_BODY "@rx ok" "id:901141,phase:4,t:none,deny,log"
|
||||
SecRule TX:TRIGGER_PHASE5 "@eq 1" "id:901151,phase:5,t:none,pass,log,msg:\'This is the phase 5.\'"
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
$t->write_file("/phase1", "should be moved/blocked before this.");
|
||||
$t->write_file("/phase2", "should be moved/blocked before this.");
|
||||
$t->write_file("/phase3", "should be moved/blocked before this.");
|
||||
$t->write_file("/phase4", "should not be moved/blocked, headers delivered before phase 4.");
|
||||
$t->write_file("/early-block", "should be moved/blocked before this.");
|
||||
$t->run();
|
||||
$t->todo_alerts();
|
||||
$t->plan(21);
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
# Redirect (302)
|
||||
like(http_get('/phase1?what=redirect302'), qr/^HTTP.*302/, 'redirect 302 - phase 1');
|
||||
like(http_get('/phase2?what=redirect302'), qr/^HTTP.*302/, 'redirect 302 - phase 2');
|
||||
like(http_get('/phase3?what=redirect302'), qr/^HTTP.*302/, 'redirect 302 - phase 3');
|
||||
is(http_get('/phase4?what=redirect302'), '', 'redirect 302 - phase 4');
|
||||
|
||||
# Redirect (301)
|
||||
like(http_get('/phase1?what=redirect301'), qr/^HTTP.*301/, 'redirect 301 - phase 1');
|
||||
like(http_get('/phase2?what=redirect301'), qr/^HTTP.*301/, 'redirect 301 - phase 2');
|
||||
like(http_get('/phase3?what=redirect301'), qr/^HTTP.*301/, 'redirect 301 - phase 3');
|
||||
is(http_get('/phase4?what=redirect301'), '', 'redirect 301 - phase 4');
|
||||
|
||||
# Block (401)
|
||||
like(http_get('/phase1?what=block401'), qr/^HTTP.*401/, 'block 401 - phase 1');
|
||||
like(http_get('/phase2?what=block401'), qr/^HTTP.*401/, 'block 401 - phase 2');
|
||||
like(http_get('/phase3?what=block401'), qr/^HTTP.*401/, 'block 401 - phase 3');
|
||||
is(http_get('/phase4?what=block401'), '', 'block 401 - phase 4');
|
||||
|
||||
# Block (403)
|
||||
like(http_get('/phase1?what=block403'), qr/^HTTP.*403/, 'block 403 - phase 1');
|
||||
like(http_get('/phase2?what=block403'), qr/^HTTP.*403/, 'block 403 - phase 2');
|
||||
like(http_get('/phase3?what=block403'), qr/^HTTP.*403/, 'block 403 - phase 3');
|
||||
is(http_get('/phase4?what=block403'), '', 'block 403 - phase 4');
|
||||
|
||||
# Nothing to detect
|
||||
like(http_get('/phase1?what=nothing'), qr/should be moved\/blocked before this./, 'nothing phase 1');
|
||||
like(http_get('/phase2?what=nothing'), qr/should be moved\/blocked before this./, 'nothing phase 2');
|
||||
like(http_get('/phase3?what=nothing'), qr/should be moved\/blocked before this./, 'nothing phase 3');
|
||||
like(http_get('/phase4?what=nothing'), qr/should not be moved\/blocked, headers delivered before phase 4./, 'nothing phase 4');
|
||||
|
||||
# early block (https://github.com/SpiderLabs/ModSecurity-nginx/issues/238)
|
||||
like(http_get('/early-block'), qr/^HTTP.*403/, 'early block 403 (https://github.com/SpiderLabs/ModSecurity-nginx/issues/238)');
|
|
@ -1,39 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# Script to adjust nginx tests to include ModSecurity directives. It enables
|
||||
# us to passively test nginx functionality with ModSecurity module enabled.
|
||||
#
|
||||
|
||||
# sh command line variations:
|
||||
#
|
||||
# for i in *.t; do cp -n $i $i.orig; perl nginx-tests-cvt.pl < $i.orig > $i; done
|
||||
# for i in *.t; do perl nginx-tests-cvt.pl < $i.orig > $i; done
|
||||
# for i in *.t; do cp $i.orig $i; done
|
||||
|
||||
my $ignore = 0;
|
||||
while (<STDIN>) {
|
||||
print $_;
|
||||
|
||||
$ignore = 1 if (/^mail {/); # skip mail_*.t mail blocks
|
||||
$ignore = 0 if (/^http {/);
|
||||
|
||||
next if ($ignore);
|
||||
|
||||
if (/^ *server_name .*;$/) {
|
||||
|
||||
next if (/^ *server_name *below;/); # skip duplication on refresh.t
|
||||
next if (/^ *server_name *many4.example.com;/); # skip duplication on http_server_name.t
|
||||
|
||||
print "
|
||||
modsecurity on;
|
||||
modsecurity_rules '
|
||||
SecRuleEngine On
|
||||
SecDebugLogLevel 9
|
||||
SecRule ARGS \"\@streq whee\" \"id:10,phase:2\"
|
||||
SecRule ARGS \"\@streq whee\" \"id:11,phase:2\"
|
||||
';
|
||||
";
|
||||
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
---
|
||||
name: Bug report for version 2.x
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Logs and dumps**
|
||||
|
||||
Output of:
|
||||
1. DebugLogs (level 9)
|
||||
2. AuditLogs
|
||||
3. Error logs
|
||||
4. If there is a crash, the core dump file.
|
||||
|
||||
_Notice:_ Be carefully to not leak any confidential information.
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
A **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case.
|
||||
|
||||
[e.g: curl "modsec-full/ca/..\\..\\..\\..\\..\\..\\/\\etc/\\passwd" or [issue-394.json](https://github.com/SpiderLabs/ModSecurity/blob/v3/master/test/test-cases/regression/issue-394.json)]
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Server (please complete the following information):**
|
||||
- ModSecurity version (and connector): [e.g. ModSecurity v3.0.1 with nginx-connector v1.0.0]
|
||||
- WebServer: [e.g. nginx-1.15.5]
|
||||
- OS (and distro): [e.g. Linux, archlinux]
|
||||
|
||||
|
||||
**Rule Set (please complete the following information):**
|
||||
- Running any public or commercial rule set? [e.g. SpiderLabs commercial rules]
|
||||
- What is the version number? [e.g. 2018-08-11]
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
|
@ -1,50 +0,0 @@
|
|||
---
|
||||
name: Bug report for version 3.x
|
||||
about: Create a report to help us improve. If you don't know a specific detail or
|
||||
piece of information leave it blank, if necessary we will help you to figure out.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Logs and dumps**
|
||||
|
||||
Output of:
|
||||
1. DebugLogs (level 9)
|
||||
2. AuditLogs
|
||||
3. Error logs
|
||||
4. If there is a crash, the core dump file.
|
||||
|
||||
_Notice:_ Be careful to not leak any confidential information.
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
A **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case.
|
||||
|
||||
[e.g: curl "modsec-full/ca/..\\..\\..\\..\\..\\..\\/\\etc/\\passwd" or [issue-394.json](https://github.com/SpiderLabs/ModSecurity/blob/v3/master/test/test-cases/regression/issue-394.json)]
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Server (please complete the following information):**
|
||||
- ModSecurity version (and connector): [e.g. ModSecurity v3.0.8 with nginx-connector v1.0.3]
|
||||
- WebServer: [e.g. nginx-1.18.0]
|
||||
- OS (and distro): [e.g. Linux, archlinux]
|
||||
|
||||
|
||||
**Rule Set (please complete the following information):**
|
||||
- Running any public or commercial rule set? [e.g. SpiderLabs commercial rules]
|
||||
- What is the version number? [e.g. 2018-08-11]
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
|
@ -1,77 +0,0 @@
|
|||
name: Quality Assurance
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
platform: [x32, x64]
|
||||
compiler: [gcc, clang]
|
||||
configure:
|
||||
- {label: "with parser generation", opt: "--enable-parser-generation" }
|
||||
- {label: "wo curl", opt: "--without-curl" }
|
||||
- {label: "wo yajl", opt: "--without-yajl" }
|
||||
- {label: "wo geoip", opt: "--without-geoip" }
|
||||
- {label: "wo lmdb", opt: "--without-lmdb" }
|
||||
- {label: "wo ssdeep", opt: "--without-ssdeep" }
|
||||
- {label: "wo lua", opt: "--without-lua" }
|
||||
- {label: "without maxmind", opt: "--without-maxmind" }
|
||||
steps:
|
||||
- name: Setup Dependencies
|
||||
run: |
|
||||
sudo add-apt-repository --yes ppa:maxmind/ppa
|
||||
sudo apt-get update -y -qq
|
||||
sudo apt-get install -y libfuzzy-dev libyajl-dev libgeoip-dev liblua5.2-dev liblmdb-dev cppcheck libmaxminddb-dev libcurl4-openssl-dev
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: build.sh
|
||||
run: ./build.sh
|
||||
- name: configure ${{ matrix.configure.label }}
|
||||
run: ./configure ${{ matrix.configure.opt }}
|
||||
- uses: ammaraskar/gcc-problem-matcher@master
|
||||
- name: make
|
||||
run: make -j `nproc`
|
||||
- name: check
|
||||
run: make check
|
||||
- name: check-static
|
||||
run: make check-static
|
||||
|
||||
build-macos:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-10.15]
|
||||
compiler: [clang]
|
||||
configure:
|
||||
- {label: "with parser generation", opt: "--enable-parser-generation" }
|
||||
- {label: "wo curl", opt: "--without-curl" }
|
||||
- {label: "wo yajl", opt: "--without-yajl" }
|
||||
- {label: "wo geoip", opt: "--without-geoip" }
|
||||
- {label: "wo lmdb", opt: "--without-lmdb" }
|
||||
- {label: "wo ssdeep", opt: "--without-ssdeep" }
|
||||
- {label: "wo lua", opt: "--without-lua" }
|
||||
- {label: "wo maxmind", opt: "--without-maxmind" }
|
||||
steps:
|
||||
- name: Setup Dependencies
|
||||
run: |
|
||||
brew install autoconf automake cppcheck lmdb libyaml lua ssdeep libmaxminddb bison
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: build.sh
|
||||
run: ./build.sh
|
||||
- name: configure ${{ matrix.configure.label }}
|
||||
run: ./configure ${{ matrix.configure.opt }}
|
||||
- uses: ammaraskar/gcc-problem-matcher@master
|
||||
- name: make
|
||||
run: make -j `sysctl -n hw.logicalcpu`
|
||||
- name: check
|
||||
run: make check
|
||||
- name: check-static
|
||||
run: make check-static
|
50
src/deps/src/ModSecurity/.gitignore
vendored
50
src/deps/src/ModSecurity/.gitignore
vendored
|
@ -1,50 +0,0 @@
|
|||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
**/Makefile
|
||||
**/Makefile.in
|
||||
aclocal.m4
|
||||
ar-lib
|
||||
autom4te.cache/
|
||||
build/libtool.m4
|
||||
build/ltoptions.m4
|
||||
build/ltsugar.m4
|
||||
build/ltversion.m4
|
||||
build/lt~obsolete.m4
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
.deps
|
||||
.libs
|
||||
.dirstamp
|
||||
src/config.h
|
||||
src/config.h.in
|
||||
src/location.hh
|
||||
src/position.hh
|
||||
src/stack.hh
|
||||
src/stamp-h1
|
||||
/test/rules_optimization
|
||||
/test/regression_tests
|
||||
/test/unit_tests
|
||||
/test-driver
|
||||
/test/massif.out.*
|
||||
/test/benchmark/benchmark
|
||||
/test/benchmark/owasp-v3/
|
||||
/test/test-cases/regression/*.trs
|
||||
/test/test-cases/regression/*.log
|
||||
/test-suite.log
|
||||
ylwrap
|
||||
missing
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
examples/simple_example_using_c/test
|
||||
/tools/rules-check/modsec-rules-check
|
||||
examples/multiprocess_c/multi
|
||||
examples/reading_logs_via_rule_message/simple_request
|
||||
examples/reading_logs_with_offset/read
|
||||
examples/using_bodies_in_chunks/simple_request
|
9
src/deps/src/ModSecurity/.gitmodules
vendored
9
src/deps/src/ModSecurity/.gitmodules
vendored
|
@ -1,9 +0,0 @@
|
|||
[submodule "test/test-cases/secrules-language-tests"]
|
||||
path = test/test-cases/secrules-language-tests
|
||||
url = https://github.com/SpiderLabs/secrules-language-tests
|
||||
[submodule "others/libinjection"]
|
||||
path = others/libinjection
|
||||
url = https://github.com/libinjection/libinjection.git
|
||||
[submodule "bindings/python"]
|
||||
path = bindings/python
|
||||
url = https://github.com/SpiderLabs/ModSecurity-Python-bindings.git
|
|
@ -1,4 +0,0 @@
|
|||
zimmerle = Felipe Zimmerle <felipe@zimmerle.org>
|
||||
rbarnett = Ryan C. Barnett <rcbarnett@gmail.com>
|
||||
csanders-git = Chaim Sanders <chaim@chaimsanders.com>
|
||||
victorhora = Victor Hora <victorminuto@gmail.com>
|
|
@ -1,552 +0,0 @@
|
|||
v3.0.9 - 2023-Apr-12
|
||||
--------------------
|
||||
|
||||
- Fix: possible segfault on reload if duplicate ip+CIDR in ip match list
|
||||
[Issue #2877, #2890 - @tomsommer, @martinhsv]
|
||||
- Add some member variable inits in Transaction class (possible segfault)
|
||||
[Issue #2886 - @GNU-Plus-Windows-User, @airween, @mdounin, @martinhsv]
|
||||
- Resolve memory leak on reload (bison-generated variable)
|
||||
[Issue #2876 - @martinhsv]
|
||||
- Support equals sign in XPath expressions
|
||||
[Issue #2328 - @dennus, @martinhsv]
|
||||
- Encode two special chars in error.log output
|
||||
[Issue #2854 - @airween, @martinhsv]
|
||||
- Add JIT support for PCRE2
|
||||
[Issue #2791 - @wfjsw, @airween, @FireBurn, @martinhsv]
|
||||
- Support comments in ipMatchFromFile file via '#' token
|
||||
[Issue #2554 - @tomsommer, @martinhsv]
|
||||
- Use name package name libmaxminddb with pkg-config
|
||||
[Issue #2595, #2596 - @frankvanbever, @ffontaine, @arnout]
|
||||
- Fix: FILES_TMP_CONTENT collection key should use part name
|
||||
[Issue #2831 - @airween]
|
||||
- Use AS_HELP_STRING instead of obsolete AC_HELP_STRING macro
|
||||
[Issue #2806 - @hughmcmaster]
|
||||
- During configure, do not check for pcre if pcre2 specified
|
||||
[Issue #2750 - @dvershinin, @martinhsv]
|
||||
- Use pkg-config to find libxml2 first
|
||||
[Issue #2714 - @hughmcmaster]
|
||||
- Fix two rule-reload memory leak issues
|
||||
[Issue #2801 - @Abce, @martinhsv]
|
||||
- Correct whitespace handling for Include directive
|
||||
[Issue #2800 - @877509395, @martinhsv]
|
||||
|
||||
|
||||
v3.0.8 - 2022-Sep-07
|
||||
--------------------
|
||||
|
||||
- Adjust parser activation rules in modsecurity.conf-recommended
|
||||
[Issue #2796 - @terjanq, @martinhsv]
|
||||
- Multipart parsing fixes and new MULTIPART_PART_HEADERS collection
|
||||
[Issue #2795 - @terjanq, @martinhsv]
|
||||
- Prevent LMDB related segfault
|
||||
[Issue #2755, #2761 - @dvershinin]
|
||||
- Fix msc_transaction_cleanup function comment typo
|
||||
[Issue #2788 - @lookat23]
|
||||
- Fix: MULTIPART_INVALID_PART connected to wrong internal variable
|
||||
[Issue #2785 - @martinhsv]
|
||||
- Restore Unique_id to include random portion after timestamp
|
||||
[Issue #2752, #2758 - @datkps11, @martinhsv]
|
||||
|
||||
v3.0.7 - 2022-May-30
|
||||
--------------------
|
||||
|
||||
- Move PCRE2 match block from member variable
|
||||
[@martinhsv]
|
||||
- Add SecArgumentsLimit, 200007 to modsecurity.conf-recommended
|
||||
[Issue #2738 - @jleproust, @martinhsv]
|
||||
- Fix memory leak when concurrent log includes REMOTE_USER
|
||||
[Issue #2727 - @liudongmiao]
|
||||
- Fix LMDB initialization issues
|
||||
[Issue #2688 - @ziollek, @martinhsv]
|
||||
- Fix initcol error message wording
|
||||
[Issue #2732 - @877509395, @martinhsv]
|
||||
- Tolerate other parameters after boundary in multipart C-T
|
||||
[Issue #1900 - @martinhsv]
|
||||
- Add DebugLog message for bad pattern in rx operator
|
||||
[Issue #2723 - @martinhsv]
|
||||
- Support PCRE2
|
||||
[Issue #2668 - @martinhsv]
|
||||
- Support SecRequestBodyNoFilesLimit
|
||||
[Issue #2670 - @airween, @martinhsv]
|
||||
- Fix misuses of LMDB API
|
||||
[Issue #2601, #2602 - @hyc]
|
||||
- Fix duplication typo in code comment
|
||||
[Issue #2677 - @gleydsonsoares]
|
||||
- Add ctl:auditEngine action support
|
||||
[Issue #2606 - @alekravch, @martinhsv]
|
||||
- Fix multiMatch msg, etc, population in audit log
|
||||
[Issue #2573 - @Sachin-M-Desai, @martinhsv]
|
||||
- Fix some name handling for ARGS_*NAMES: regex SecRuleUpdateTargetById, etc.
|
||||
[Issue #2627, #2648 - @lontchianicet, @victorserbu2709, @martinhsv]
|
||||
- Adjust confusing variable name in setRequestBody method
|
||||
[Issue #2635 - @Mesar-Ali, @martinhsv]
|
||||
- Multipart names/filenames may include single quote if double-quote enclosed
|
||||
[Issue #2352 - @martinhsv]
|
||||
- Add SecRequestBodyJsonDepthLimit to modsecurity.conf-recommended
|
||||
[Issue #2647 - @theMiddleBlue, @airween, @877509395 ,@martinhsv]
|
||||
|
||||
|
||||
v3.0.6 - 2021-Nov-19
|
||||
-------------------------------------
|
||||
|
||||
- Support configurable limit on depth of JSON parsing
|
||||
[@theMiddleBlue, @martinhsv]
|
||||
|
||||
v3.0.5 - 2021-Jul-07
|
||||
--------------------
|
||||
|
||||
- Handle URI received with uri-fragment
|
||||
[@martinhsv]
|
||||
- Having ARGS_NAMES, variables proxied
|
||||
[@zimmerle, @martinhsv, @KaNikita]
|
||||
- Use explicit path for cross-compile environments.
|
||||
[Issue #2485 - @dtoubelis]
|
||||
- Fix: FILES variable does not use multipart part name for key
|
||||
[Issue #2377 - @martinhsv]
|
||||
- Replaces put with setenv in SetEnv action
|
||||
[Issue #2469 - @martinhsv, @WGH-, @zimmerle]
|
||||
- Regression: Mark the test as failed in case of segfault.
|
||||
[@zimmerle]
|
||||
- Regex key selection should not be case-sensitive
|
||||
[Issue #2296, #2107, #2297 - @michaelgranzow-avi, @victorhora,
|
||||
@airween, @martinhsv, @zimmerle]
|
||||
- Fix: Only delete Multipart tmp files after rules have run
|
||||
[Issue #2427 - @martinhsv]
|
||||
- Fixed MatchedVar on chained rules
|
||||
[Issue #2423, #2435, #2436 - @michaelgranzow-avi]
|
||||
- Add support for new operator rxGlobal
|
||||
[@martinhsv]
|
||||
- Fix maxminddb link on FreeBSD
|
||||
[Issue #2131 - @granalberto, @zimmerle]
|
||||
- Fix IP address logging in Section A
|
||||
[Issue #2300 - @inaratech, @zavazingo, @martinhsv]
|
||||
- Adds support to lua 5.4
|
||||
[@zimmerle]
|
||||
- GeoIP: switch to GEOIP_MEMORY_CACHE from GEOIP_INDEX_CACHE
|
||||
[Issues #2378, #2186 - @defanator]
|
||||
- rx: exit after full match (remove /g emulation); ensure capture
|
||||
groups occuring after unused groups still populate TX vars
|
||||
[Issue #2336 - @martinhsv]
|
||||
- Correct CHANGES file entry for #2234
|
||||
- Add support to test framework for audit log content verification
|
||||
and add regression tests for issues #2000, #2196
|
||||
- Support configurable limit on number of arguments processed
|
||||
[Issue #2234 - @jleproust, @martinhsv]
|
||||
- Multipart Content-Dispostion should allow field: filename*=
|
||||
[@martinhsv]
|
||||
- Fix rule-update-target for non-regex
|
||||
[Issue 2251 - @martinhsv]
|
||||
- Fix configure script when packaging for Buildroot
|
||||
[Issue 2235 - @frankvanbever]
|
||||
- modsecurity.pc.in: add Libs.private
|
||||
[Issue #1918, #2253 - @ffontaine, @Dridi, @victorhora]
|
||||
|
||||
v3.0.4 - 2020-Jan-13
|
||||
--------------------
|
||||
|
||||
- Fix: audit log data omitted when nolog,auditlog
|
||||
[@martinhsv]
|
||||
- Fix: ModSecurity 3.x inspectFile operator does not pass
|
||||
FILES_TMPNAMES parameter to lua engine
|
||||
[Issue #2204, #2205 - @kadirerdogan]
|
||||
- XML: Remove error messages from stderr
|
||||
[Issue #2010 - @JaiHarpalani, @zimmerle]
|
||||
- Filter comment or blank line for pmFromFile operator
|
||||
[Issue #1645 - @LeeShan87, @victorhora, @tdoubley]
|
||||
- Additional adjustment to Cookie header parsing
|
||||
[@martinhsv]
|
||||
- Restore chained rule part H logging to be more like 2.9 behaviour
|
||||
[Issue #2196 - @martinhsv]
|
||||
- Small fixes in log messages to help debugging the file upload
|
||||
[Issue #2130 - @airween]
|
||||
- Fix Cookie header parsing issues
|
||||
[Issue #2201 - @airween, @martinhsv]
|
||||
- Fix rules with nolog are logging to part H
|
||||
[Issue #2196 - @martinhsv]
|
||||
- Fix argument key-value pair parsing cases
|
||||
[Issue #1904 - @martinhsv]
|
||||
- Fix: audit log part for response body for JSON format to be E
|
||||
[Issue #2066 - @martinhsv, @zimmerle]
|
||||
- Make sure m_rulesMessages is filled after successfull match
|
||||
[Issue #2000, #2048 - @victorhora, @defanator]
|
||||
- Fix @pm lookup for possible matches on offset zero.
|
||||
[@zimmerle, @afoxdavidi, @martinhsv, @marshal09]
|
||||
- Regex lookup on the key name instead of COLLECTION:key
|
||||
[@rdiperri-yottaa, @danbiagini-work, @mmelo-yottaa, @zimmerle]
|
||||
- Missing throw in Operator::instantiate
|
||||
[Issue #2106 - @marduone]
|
||||
- Making block action execution dependent of the SecEngine status
|
||||
[Issue #2113, #2111 - @theMiddleBlue, @airween]
|
||||
- Making block action execution dependent of the SecEngine status
|
||||
[Issue #1960 - @theMiddleBlue, @zimmerle, @airween, @victorhora]
|
||||
- Having body limits to respect the rule engine state
|
||||
[@zimmerle]
|
||||
- Fix SecRuleUpdateTargetById does not match regular expressions
|
||||
[Issue #1872 - @zimmerle, @anush-cr, @victorhora, @j0k2r]
|
||||
- Adds missing check for runtime ctl:ruleRemoveByTag
|
||||
[Issue #2102, #2099 - @airween]
|
||||
- Adds a new operator verifySVNR that checks for Austrian social
|
||||
security numbers.
|
||||
[Issue #2063 - @Rufus125]
|
||||
- Fix variables output in debug logs
|
||||
[Issue #2057 - @jleproust]
|
||||
- Correct typo validade in log output
|
||||
[Issue #2059 - @nerrehmit]
|
||||
- fix/minor: Error encoding hexa decimal.
|
||||
[Issue #2068 - @tech-ozon-io]
|
||||
- Limit more log variables to 200 characters.
|
||||
[Issue #2073 - @jleproust]
|
||||
- parser: fix parsed file names
|
||||
[@zimmerle]
|
||||
- Allow empty anchored variable
|
||||
[Issue #2024 - @airween]
|
||||
- Fixed FILES_NAMES collection after the end of multipart parsing
|
||||
[Issue #2016 - @airween]
|
||||
- Fixed validateByteRange parsing method
|
||||
[Issue #2017 - @airween]
|
||||
- Removes a memory leak on the JSON parser
|
||||
[@zimmerle]
|
||||
- Enables LMDB on the regression tests.
|
||||
[Issue #2011, #2008 - @WGH-, @mdunc]
|
||||
- Fix: Extra whitespace in some configuration directives causing error
|
||||
[Issue #2006 - @porjo, @zimmerle]
|
||||
- Refactoring on Regex and SMatch classes.
|
||||
[@WGH-]
|
||||
- Fixed buffer overflow in Utils::Md5::hexdigest()
|
||||
[Issue #2002 - @defanator]
|
||||
- Implemented merge() method for ConfigInt, ConfigDouble, ConfigString
|
||||
[Issue #1990 - @defanator]
|
||||
- Adds initially support to the drop action.
|
||||
[@zimmerle]
|
||||
- Complete merging of particular rule properties
|
||||
[Issue #1978 - @defanator]
|
||||
- Replaces AC_CHECK_FILE with 'test -f'
|
||||
[Issue #1984 - @chuckwolber]
|
||||
- Fix inet addr handling on 64 bit big endian systems
|
||||
[Issue #1980 - @airween]
|
||||
- Fix tests on FreeBSD
|
||||
[Issue #1973 - @defanator]
|
||||
- Changes ENV test case to read the default MODSECURTIY env var
|
||||
[Issue #1969 - @zimmerle, @airween, @inittab]
|
||||
- Regression: Sets MODSECURITY env var during the tests execution
|
||||
[Issue #1969 - @zimmerle, @airween, @inittab]
|
||||
- Fix setenv action to strdup key=variable
|
||||
[@zimmerle]
|
||||
- Allow 0 length JSON requests.
|
||||
[Issue #1822 - @allanbomsft, @zimmerle, @victorhora, @marcstern]
|
||||
- Fix "make dist" target to include default configuration
|
||||
[Issue #1966 - @defanator]
|
||||
- Replaced log locking using mutex with fcntl lock
|
||||
[Issue #1949, #1927 - @Cloaked9000]
|
||||
- Correct the usage of modsecurity::Phases::NUMBER_OF_PHASES
|
||||
[Issue #1959 - @weliu]
|
||||
- Adds support to multiple ranges in ctl:ruleRemoveById
|
||||
[Issue #1956 - @theseion, @victorhora, @zimmerle]
|
||||
- Rule variable interpolation broken
|
||||
[Issue #1961 - @soonum, @zimmerle]
|
||||
- Make the boundary check less strict as per RFC2046
|
||||
[Issue #1943 - @victorhora, @allanbomsft]
|
||||
- Fix buffer size for utf8toUnicode transformation
|
||||
[Issue #1208 - @katef, @victorhora]
|
||||
|
||||
|
||||
v3.0.3 - 2018-Nov-05
|
||||
--------------------
|
||||
|
||||
- Fix double macros bug
|
||||
[Issue #1943 - @supplient, @zimmerle]
|
||||
- Override the default status code if not suitable to redirect action
|
||||
[Issue #1850 - @zimmerle, @victorhora]
|
||||
- parser: Fix the support for CRLF configuration files
|
||||
[Issue #1945 - @zimmerle, @defanator, @kjakub]
|
||||
- Organizes the server logs
|
||||
[0xb7c36 and 0x5ac20 - @zimmerle, @steven-j-wojcik]
|
||||
- m_lineNumber in Rule not mapping with the correct line number in file
|
||||
[Issue #1844 - @zimmerle, @victorhora, @xizeng]
|
||||
- Using shared_ptr instead of unique_ptr on rules exceptions
|
||||
[Issue #1697 - @zimmerle, @brianp9906, @victorhora, @LeSwiss, @defanator]
|
||||
- Changes debuglogs schema to avoid unecessary str allocation
|
||||
[0xb2840 - @zimmerle]
|
||||
- Fix the SecUnicodeMapFile and SecUnicodeCodePage
|
||||
[0x3094d - @zimmerle, @victorhora]
|
||||
- Changes the timing to save the rule message
|
||||
[0xca270 - @zimmerle]
|
||||
- Fix crash in msc_rules_add_file() when using disruptive action in chain
|
||||
[Issue #1849 - @victorhora, @zimmerle, @rperper]
|
||||
- Fix memory leak in AuditLog::init()
|
||||
[Issue #1897 - @weliu]
|
||||
- Fix RulesProperties::appendRules()
|
||||
[Issue #1901 - @steven-j-wojcik]
|
||||
- Fix RULE lookup in chained rules
|
||||
[0x3077c - @zimmerle]
|
||||
- @ipMatch "Could not add entry" on slash/32 notation in 2.9.0
|
||||
[Issue #849 - @zimmerle, @dune73]
|
||||
- Using values after transformation at MATCHED_VARS
|
||||
[0x14316 - @zimmerle]
|
||||
- Adds support to UpdateActionById.
|
||||
[Issue #1800 - @zimmerle, @victorhora, @NisariAIT]
|
||||
- Add correct C function prototypes for msc_init and msc_create_rule_set
|
||||
[Issue #1922 - @steven-j-wojcik]
|
||||
- Allow LuaJIT 2.1 to be used
|
||||
[Issue #1909 - @victorhora, @mdunc]
|
||||
- Match m_id JSON log with RuleMessage and v2 format
|
||||
[Issue #1185 - @victorhora]
|
||||
- Adds support to setenv action.
|
||||
[Issue #1044 - @zimmerle]
|
||||
- Adds new transaction constructor that accepts the transaction id
|
||||
as parameter.
|
||||
[Issue #1627 - @defanator, @zimmerle]
|
||||
- Adds request IDs and URIs to the debug log
|
||||
[Issue #1627 - @defanator, @zimmerle]
|
||||
- Treating variables exception on load-time instead of run time.
|
||||
[0x028e0 and 0x275a1 - @zimmerle]
|
||||
- Fix: function m.setvar in Lua scripts and add testcases
|
||||
[Issue #1859 - @nowaits, @victorhora]
|
||||
- Fix SecResponseBodyAccess and ctl:requestBodyAccess directives
|
||||
[Issue #1531 - @victorhora, @defanator]
|
||||
- Fix OpenBSD build
|
||||
[Issue #1841 - @victorhora, @zimmerle, @juanfra684]
|
||||
- Fix parser to support GeoLookup with MaxMind
|
||||
[Issue #1884, #1895 - @victorhora, @everping]
|
||||
- parser: Fix simple quote setvar in the end of the line
|
||||
[Issue #1831 - @zimmerle, @csanders-git]
|
||||
- Fix pc file
|
||||
[Issue #1847 - @gquintard]
|
||||
- modsec_rules_check: uses the gnu `.la' instead of `.a' file
|
||||
[Issue #1853 - @ste7677, @victorhora, @zimmerle]
|
||||
- good practices: Initialize variables before use it
|
||||
[Issue #1889 - Marc Stern]
|
||||
- Fix utf-8 character encoding conversion
|
||||
[Issue #1794 - @tinselcity, @zimmerle]
|
||||
- Adds support for ctl:requestBodyProcessor=URLENCODED
|
||||
[Issue #1797 - @victorhora]
|
||||
- Add LUA compatibility for CentOS and try to use LuaJIT first if available
|
||||
[Issue #1622 - @victorhora, @dmitryzykov]
|
||||
- Allow LuaJIT to be used
|
||||
[Issue #1809 - @victorhora, @p0pr0ck5]
|
||||
- Implement support for Lua 5.1
|
||||
[Issue #1809 - @p0pr0ck5, @victorhora]
|
||||
- Variable names must match fully, not partially. Match should be case
|
||||
insensitive.
|
||||
[Issue #1818, #1820, #1810, #1808 - @michaelgranzow-avi, @victorhora,
|
||||
@theMiddleBlue, @airween, @zimmerle,
|
||||
@LeeShan87]
|
||||
- Improves the performance while loading the rules
|
||||
[Issue #1735 - @zimmerle, @p0pr0ck5, @victorhora]
|
||||
- Allow empty strings to be evaluated by regex::searchAll
|
||||
[Issue #1799, #1785 - @victorhora, @XuanHuyDuong, @zimmerle]
|
||||
- Adds basic pkg-config info
|
||||
[Issue #1790 - @gquintard, @zimmerle]
|
||||
- Fixed LMDB collection errors
|
||||
[Issue #1787 - @airween, @zimmerle]
|
||||
- Fixed false positive MULTIPART_UNMATCHED_BOUNDARY errors
|
||||
[Issue #1747, #1924 - @airween, @victorhora, @defanator, @zimmerle]
|
||||
- Fix ip tree lookup on netmask content
|
||||
[Issue #1793 - @tinselcity, @zimmerle]
|
||||
- Changes the behavior of the default sec actions
|
||||
[Issue #1629 - @mirkodziadzka-avi, @zimmerle, @victorhora]
|
||||
- Refactoring on {global,ip,resources,session,tx,user} collections
|
||||
[Issue #1754, #1778 - @LeeShan87, @zimmerle, @victorhora, @wwd5613,
|
||||
@sobigboy]
|
||||
- Fix race condition in UniqueId::uniqueId()
|
||||
[Issue #1786 - @weliu]
|
||||
- Fix memory leak in error message for msc_rules_merge C APIs
|
||||
[Issue #1765 - @weliu]
|
||||
- Return false in SharedFiles::open() when an error happens
|
||||
[Issue #1783 - @weliu]
|
||||
- Use rvalue reference in ModSecurity::serverLog
|
||||
[Issue #1769 - @weliu]
|
||||
- Build System: Fix when multiple lines for curl version.
|
||||
[Issue #1771 - @Artistan]
|
||||
- Checks if response body inspection is enabled before process it
|
||||
[Issue #1643 - @zoltan-fedor, @dennus, @defanator, @zimmerle]
|
||||
- Code Cleanup.
|
||||
[Issue #1757, #1755, #1756, #1761 - @p0pr0ck5]
|
||||
- Fix setvar parsing of quoted data
|
||||
[Issue #1733, #1759, #1775 - @victorhora, @JaiHarpalani, @defanator]
|
||||
- Fix LDFLAGS for unit tests.
|
||||
[Issue #1758 - @smlx]
|
||||
- Adds time stamp back to the audit logs
|
||||
[Issue #1762 - @Pjack, @zimmerle]
|
||||
- Disables skip counter if debug log is disabled
|
||||
[@zimmerle]
|
||||
- Cosmetics: Represents amount of skipped rules without decimal
|
||||
[Issue #1737 - @p0pr0ck5]
|
||||
- Add missing escapeSeqDecode, urlEncode and trimLeft/Right tfns to parser
|
||||
[Issue #1752 - @victorhora]
|
||||
- Fix STATUS var parsing and accept STATUS_LINE var for v2 backward comp.
|
||||
[Issue #1738 - @victorhora]
|
||||
- Fix memory leak in modsecurity::utils::expandEnv()
|
||||
[Issue #1750 - @defanator]
|
||||
- Initialize m_dtd member in ValidateDTD class as NULL
|
||||
[Issue #1751 - @airween]
|
||||
- Fix broken @detectxss operator regression test case
|
||||
[Issue #1739 - @p0pr0ck5]
|
||||
- Fix utils::string::ssplit() to handle delimiter in the end of string
|
||||
[Issue #1743, #1744 - @defanator]
|
||||
- Fix variable FILES_TMPNAMES
|
||||
[Issue #1646, #1610 - @victorhora, @zimmerle, @defanator]
|
||||
- Fix memory leak in Collections
|
||||
[Issue #1729, #1730 - @defanator]
|
||||
|
||||
|
||||
v3.0.2 - 2018-Apr-03
|
||||
--------------------
|
||||
|
||||
- Fix lib version information while generating the .so file
|
||||
[@gl1f1v21, @zimmerle]
|
||||
|
||||
v3.0.1 - 2018-Apr-02
|
||||
--------------------
|
||||
|
||||
- Adds support for ctl:ruleRemoveByTag
|
||||
[@zimmerle, @weliu]
|
||||
- Fix SecUploadDir configuration merge
|
||||
[Issue #1720 - @zimmerle, @gjvanetten]
|
||||
- Include all prerequisites for "make check" into dist archive
|
||||
[Issue #1716 - @defanator]
|
||||
- Fix: Reverse logic of checking output in @inspectFile
|
||||
[Issue #1715 - @defanator]
|
||||
- Adds support to libMaxMind
|
||||
[Issue #1307 - @zimmerle, @defanator]
|
||||
- Adds capture action to detectXSS
|
||||
[Issue #1698 - @victorhora]
|
||||
- Temporarily accept invalid MULTIPART_SEMICOLON_MISSING operator
|
||||
[Issue #1701 - @victorhora]
|
||||
- Adds capture action to detectSQLi
|
||||
[Issue #1698 - @zimmerle]
|
||||
- Adds capture action to rbl
|
||||
[Issue #1698 - @zimmerle]
|
||||
- Adds capture action to verifyCC
|
||||
[Issue #1698 - @michaelgranzow-avi, @zimmerle]
|
||||
- Adds capture action to verifySSN
|
||||
[Issue #1698 - @zimmerle]
|
||||
- Adds capture action to verifyCPF
|
||||
[Issue #1698 - @zimmerle]
|
||||
- Prettier error messages for unsupported configurations (UX)
|
||||
[@victorhora]
|
||||
- Add missing verify*** transformation statements to parser
|
||||
[Issue #1006 and #1007 - @victorhora]
|
||||
- Fix a set of compilation warnings
|
||||
[Issue #1650 - @zimmerle, @JayCase]
|
||||
- Check for disruptive action on SecDefaultAction.
|
||||
[Issue #1614 - @zimmerle, @michaelgranzow-avi]
|
||||
- Fix block-block infinite loop.
|
||||
[Issue #1614 - @zimmerle, @michaelgranzow-avi]
|
||||
- Correction remove_by_tag and remove_by_msg logic.
|
||||
[Issue #1636 - @Minasu]
|
||||
- Fix LMDB compile error
|
||||
[Issue #1691 - @airween]
|
||||
- Fix msc_who_am_i() to return pointer to a valid C string
|
||||
[Issue #1640 - @defanator]
|
||||
- Added some cosmetics to autoconf related code
|
||||
[Issue #1652 - @airween]
|
||||
- Fix "make dist" target to include necessary headers for Lua
|
||||
[Issue #1678 - @defanator]
|
||||
- Fix "include /foo/*.conf" for single matched object in directory
|
||||
[Issue #1677 - @defanator, @zimmerle]
|
||||
- Add missing Base64 transformation statements to parser
|
||||
[Issue #1632 - @victorhora, @zimmerle]
|
||||
- Fixed resource load on ip match from file
|
||||
[#1674 - @zimmerle, @StefaanSeys]
|
||||
- Fixed examples compilation while using disable-shared
|
||||
[#1670 - @zimmerle, @ivanbaldo]
|
||||
- Fixed compilation issue while xml is disabled
|
||||
[0x243028 - @zimmerle]
|
||||
- Having LDADD and LDFLAGS organized on Makefile.am
|
||||
[0xd0e85e - @zimmerle]
|
||||
- Checking std::deque size before use it
|
||||
[0x217cbf - @zimmerle, Yaron Dayagi]
|
||||
- perf improvement: Added the concept of RunTimeString and removed
|
||||
all run time parser.
|
||||
[0x3eae51 0x0320e0 0xb5688f 0xfe47a9 0xfa9842 0x1affc3 0x079de4
|
||||
0xc7c04f 0x5262ea 0x01974a 0xd5ee1e - @zimmerle]
|
||||
- perf improvement: Checks debuglog level before format debug msg
|
||||
[0x42ee9 - @zimmerle]
|
||||
- perf. improvement/rx: Only compute dynamic regex in case of macro
|
||||
[0x91ff3 - @zimmerle]
|
||||
- Fix uri on the benchmark utility
|
||||
[0x63bec - @zimmerle]
|
||||
- disable Lua on systems with liblua5.1
|
||||
[Issue #1639 - @victorhora, @defanator]
|
||||
|
||||
v3.0.0 - 2017-Dec-13
|
||||
--------------------
|
||||
|
||||
- Improvements on LUA build scripts and support for LUA 5.2.
|
||||
[Issue #1617 and #1622 - @victorhora, @zimmerle]
|
||||
- Fix compilation error with disable_debug_log flag
|
||||
[0xfd84e - Izik Abramov]
|
||||
- Improvements on the benchmark tool.
|
||||
[Issue #1615 - @zimmerle]
|
||||
- Fix lua headers on the build scripts
|
||||
[Issue #1621 - @Minasu]
|
||||
- Refactoring on the JSON parser.
|
||||
[Issue #1576, #1577 - Tobias Gutknecht, @zimmerle, @victorhora, @marcstern]
|
||||
- Adds support to WEBAPPID variable.
|
||||
[Issue #1027 - @zimmerle, @victorhora]
|
||||
- Adds support for SecWebAppId.
|
||||
[Issue #1442 - @zimmerle, @victorhora]
|
||||
- Adds support for SecRuleRemoveByTag.
|
||||
[Issue #1476 - @zimmerle, @victorhora]
|
||||
- Adds support for update target by message.
|
||||
[Issue #1474 - @zimmerle, @victorhora]
|
||||
- Adds support to SecRuleScript directive.
|
||||
[Issue #994 - @zimmerle]
|
||||
- Adds support for the exec action.
|
||||
[Issue #1050 - @zimmerle]
|
||||
- Adds support for transformations inside Lua engine
|
||||
[Issue #994 - @zimmerle]
|
||||
- Adds initial support for Lua engine.
|
||||
[Issue #994 - @zimmerle]
|
||||
- Adds support for @inspectFile operator.
|
||||
[Issue #999 - @zimmerle, @victorhora]
|
||||
- Adds support for RESOURCE variable collection.
|
||||
[Issue #1014 - @zimmerle, @victorhora]
|
||||
- Adds support for @fuzzyHash operator.
|
||||
[Issue #997 - @zimmerle]
|
||||
- Fix build on non x86 arch build
|
||||
[Issue #1598 - @athmane]
|
||||
- Fix memory issue while changing rule target dynamic
|
||||
[Issue #1590 - @zimmerle, @slabber]
|
||||
- Fix log while displaying the name of a dict selection by regex.
|
||||
[@zimmerle]
|
||||
- Setting http response code on the auditlog.
|
||||
[Issue #1592 - @zimmerle]
|
||||
- Refactoring on RuleMessage class, now accepting http code as parameter.
|
||||
[@zimmerle]
|
||||
- Having disruptive msgs as disruptive [instead of warnings] on audit log
|
||||
[Issue #1592 - @zimmerle, @nobodysz]
|
||||
- Parser: Pipes are no longer welcomed inside regex dict element selection.
|
||||
[Issue #1591 - @zimmerle, @slabber]
|
||||
- Avoids unicode initialization on every rules object
|
||||
[Issue #1563 - @zimmerle, @Tiki-God, @sethinsd, @Cloaked9000, @AnoopAlias,
|
||||
@intelbg]
|
||||
- Makes clear to the user whenever the audit log is empty due to missing
|
||||
JSON support.
|
||||
[Issue #1585 - @zimmerle]
|
||||
- Makes auditlog more verbose on debug logs
|
||||
[Issue: #1559 - @zimmerle]
|
||||
- Enable support for AuditLogFormat
|
||||
Issue: #1583, #1493 and #1453 - @victorhora]
|
||||
- Adds macro expansion for @rx operator
|
||||
[Issue: #1528, #1536 - @asterite3, @zimmerle]
|
||||
- Consideres under quoted variable while loading the rules.
|
||||
[Felipe Zimmerle/@zimmerle, Victor Hora/@victorhora]
|
||||
- Store the connection and url parameters in std::string
|
||||
[Issue: #1571 - @majordaw]
|
||||
- Eliminate some reorder and sign warnings
|
||||
[Issue: #1572 - Dávid Major/@majordaw]
|
||||
- Makes parallel logging to work when SELinux is enabled.
|
||||
[Issue: #1562 - David Buckle/@met3or]
|
||||
- Adds possibility to run the pm operator inside a mutex to avoid concurrent
|
||||
access while working on a thread environment. This option is a compilation
|
||||
flag.
|
||||
[Felipe Zimmerle/@zimmerle]
|
||||
|
||||
|
||||
v3.0.0-rc1 - 2017-Aug-28
|
||||
------------------------
|
||||
|
||||
Very first public version.
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,353 +0,0 @@
|
|||
|
||||
if TEST_UTILITIES
|
||||
export MAYBE_TEST = test
|
||||
endif
|
||||
|
||||
if EXAMPLES
|
||||
export MAYBE_EXAMPLES = examples
|
||||
endif
|
||||
|
||||
|
||||
SUBDIRS = \
|
||||
others \
|
||||
src \
|
||||
doc \
|
||||
tools \
|
||||
$(MAYBE_EXAMPLES) \
|
||||
$(MAYBE_TEST)
|
||||
|
||||
|
||||
|
||||
# make clean
|
||||
CLEANFILES =
|
||||
|
||||
ACLOCAL_AMFLAGS = -I build
|
||||
|
||||
# make maintainer-clean
|
||||
MAINTAINERCLEANFILES = \
|
||||
aclocal.m4 \
|
||||
ar-lib \
|
||||
build/libtool.m4 \
|
||||
build/lt~obsolete.m4 \
|
||||
build/ltoptions.m4 \
|
||||
build/ltsugar.m4 \
|
||||
build/ltversion.m4 \
|
||||
coding-style.txt \
|
||||
compile \
|
||||
config.guess \
|
||||
config.sub \
|
||||
configure \
|
||||
cppcheck.txt \
|
||||
depcomp \
|
||||
install-sh \
|
||||
ltmain.sh \
|
||||
Makefile.in \
|
||||
missing \
|
||||
test/modsec-shared-collections \
|
||||
test/modsec-shared-collections-lock \
|
||||
test-suite-drd.log \
|
||||
test-suite-helgrind.log \
|
||||
test-suite-memcheck.log \
|
||||
ylwrap
|
||||
|
||||
parser:
|
||||
cat src/parser/seclang-parser.hh | sed "s/return \*new (yyas_<T> ()) T (t)/return *new (yyas_<T> ()) T (std::move((T\&)t))/g" > src/parser/seclang-parser.hh.fix && mv src/parser/seclang-parser.hh.fix src/parser/seclang-parser.hh
|
||||
|
||||
|
||||
|
||||
cppcheck:
|
||||
@cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \
|
||||
-D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \
|
||||
--suppressions-list=./test/cppcheck_suppressions.txt \
|
||||
--enable=warning,style,performance,portability,unusedFunction,missingInclude \
|
||||
--inconclusive \
|
||||
--template="warning: {file},{line},{severity},{id},{message}" \
|
||||
-I headers -I . -I others -I src -I others/mbedtls -I src/parser \
|
||||
--error-exitcode=1 \
|
||||
-i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \
|
||||
--force --verbose .
|
||||
|
||||
|
||||
check-static: cppcheck
|
||||
|
||||
check-style: check-coding-style
|
||||
|
||||
check-coding-style:
|
||||
@cpplint.py \
|
||||
$$(find . -name "*.h" -o -name "*.cc" | xargs) 2>&1 \
|
||||
| egrep -v $$(echo -n "catchall" ; \
|
||||
for i in $$(cat test/coding_style_suppressions.txt); do echo -n "|"$$i; done) \
|
||||
| sed 's/^\./warning: ./g' > coding-style.txt
|
||||
-cat coding-style.txt
|
||||
|
||||
|
||||
@VALGRIND_CHECK_RULES@
|
||||
VALGRIND_SUPPRESSIONS_FILES = valgrind_suppressions.txt
|
||||
|
||||
LOG_DRIVER = env $(SHELL) $(top_srcdir)/test/custom-test-driver
|
||||
AM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS;
|
||||
LOG_COMPILER=test/test-suite.sh
|
||||
|
||||
# for i in `find test/test-cases -iname *.json`; do echo TESTS+=$i; done
|
||||
TESTS=
|
||||
TESTS+=test/test-cases/regression/action-allow.json
|
||||
TESTS+=test/test-cases/regression/action-block.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_request_body_access.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_request_body_processor.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_engine.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_audit_engine.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_id.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_by_tag.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_id.json
|
||||
TESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json
|
||||
TESTS+=test/test-cases/regression/action-disruptive.json
|
||||
TESTS+=test/test-cases/regression/action-exec.json
|
||||
TESTS+=test/test-cases/regression/action-id.json
|
||||
TESTS+=test/test-cases/regression/action-initcol.json
|
||||
TESTS+=test/test-cases/regression/action-msg.json
|
||||
TESTS+=test/test-cases/regression/action-setenv.json
|
||||
TESTS+=test/test-cases/regression/action-setrsc.json
|
||||
TESTS+=test/test-cases/regression/action-setsid.json
|
||||
TESTS+=test/test-cases/regression/action-setuid.json
|
||||
TESTS+=test/test-cases/regression/actions.json
|
||||
TESTS+=test/test-cases/regression/action-skip.json
|
||||
TESTS+=test/test-cases/regression/action-tag.json
|
||||
TESTS+=test/test-cases/regression/action-tnf-base64.json
|
||||
TESTS+=test/test-cases/regression/action-xmlns.json
|
||||
TESTS+=test/test-cases/regression/auditlog.json
|
||||
TESTS+=test/test-cases/regression/collection-case-insensitive.json
|
||||
TESTS+=test/test-cases/regression/collection-lua.json
|
||||
TESTS+=test/test-cases/regression/collection-regular_expression_selection.json
|
||||
TESTS+=test/test-cases/regression/collection-resource.json
|
||||
TESTS+=test/test-cases/regression/collection-tx.json
|
||||
TESTS+=test/test-cases/regression/collection-tx-with-macro.json
|
||||
TESTS+=test/test-cases/regression/config-body_limits.json
|
||||
TESTS+=test/test-cases/regression/config-calling_phases_by_name.json
|
||||
TESTS+=test/test-cases/regression/config-include-bad.json
|
||||
TESTS+=test/test-cases/regression/config-include.json
|
||||
TESTS+=test/test-cases/regression/config-remove_by_id.json
|
||||
TESTS+=test/test-cases/regression/config-remove_by_msg.json
|
||||
TESTS+=test/test-cases/regression/config-remove_by_tag.json
|
||||
TESTS+=test/test-cases/regression/config-response_type.json
|
||||
TESTS+=test/test-cases/regression/config-secdefaultaction.json
|
||||
TESTS+=test/test-cases/regression/config-secremoterules.json
|
||||
TESTS+=test/test-cases/regression/config-update-action-by-id.json
|
||||
TESTS+=test/test-cases/regression/config-update-target-by-id.json
|
||||
TESTS+=test/test-cases/regression/config-update-target-by-msg.json
|
||||
TESTS+=test/test-cases/regression/config-update-target-by-tag.json
|
||||
TESTS+=test/test-cases/regression/config-xml_external_entity.json
|
||||
TESTS+=test/test-cases/regression/debug_log.json
|
||||
TESTS+=test/test-cases/regression/directive-sec_rule_script.json
|
||||
TESTS+=test/test-cases/regression/issue-1152.json
|
||||
TESTS+=test/test-cases/regression/issue-1528.json
|
||||
TESTS+=test/test-cases/regression/issue-1565.json
|
||||
TESTS+=test/test-cases/regression/issue-1576.json
|
||||
TESTS+=test/test-cases/regression/issue-1591.json
|
||||
TESTS+=test/test-cases/regression/issue-1725.json
|
||||
TESTS+=test/test-cases/regression/issue-1743.json
|
||||
TESTS+=test/test-cases/regression/issue-1785.json
|
||||
TESTS+=test/test-cases/regression/issue-1812.json
|
||||
TESTS+=test/test-cases/regression/issue-1831.json
|
||||
TESTS+=test/test-cases/regression/issue-1844.json
|
||||
TESTS+=test/test-cases/regression/issue-1850.json
|
||||
TESTS+=test/test-cases/regression/issue-1941.json
|
||||
TESTS+=test/test-cases/regression/issue-1943.json
|
||||
TESTS+=test/test-cases/regression/issue-1956.json
|
||||
TESTS+=test/test-cases/regression/issue-1960.json
|
||||
TESTS+=test/test-cases/regression/issue-2099.json
|
||||
TESTS+=test/test-cases/regression/issue-2000.json
|
||||
TESTS+=test/test-cases/regression/issue-2111.json
|
||||
TESTS+=test/test-cases/regression/issue-2196.json
|
||||
TESTS+=test/test-cases/regression/issue-2423-msg-in-chain.json
|
||||
TESTS+=test/test-cases/regression/issue-2427.json
|
||||
TESTS+=test/test-cases/regression/issue-2296.json
|
||||
TESTS+=test/test-cases/regression/issue-394.json
|
||||
TESTS+=test/test-cases/regression/issue-849.json
|
||||
TESTS+=test/test-cases/regression/issue-960.json
|
||||
TESTS+=test/test-cases/regression/misc.json
|
||||
TESTS+=test/test-cases/regression/misc-variable-under-quotes.json
|
||||
TESTS+=test/test-cases/regression/offset-variable.json
|
||||
TESTS+=test/test-cases/regression/operator-detectsqli.json
|
||||
TESTS+=test/test-cases/regression/operator-detectxss.json
|
||||
TESTS+=test/test-cases/regression/operator-fuzzyhash.json
|
||||
TESTS+=test/test-cases/regression/operator-inpectFile.json
|
||||
TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json
|
||||
TESTS+=test/test-cases/regression/operator-pm.json
|
||||
TESTS+=test/test-cases/regression/operator-rx.json
|
||||
TESTS+=test/test-cases/regression/operator-rxGlobal.json
|
||||
TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json
|
||||
TESTS+=test/test-cases/regression/operator-validate-byte-range.json
|
||||
TESTS+=test/test-cases/regression/operator-verifycc.json
|
||||
TESTS+=test/test-cases/regression/operator-verifycpf.json
|
||||
TESTS+=test/test-cases/regression/operator-verifyssn.json
|
||||
TESTS+=test/test-cases/regression/operator-verifysvnr.json
|
||||
TESTS+=test/test-cases/regression/request-body-parser-json.json
|
||||
TESTS+=test/test-cases/regression/request-body-parser-multipart-crlf.json
|
||||
TESTS+=test/test-cases/regression/request-body-parser-multipart.json
|
||||
TESTS+=test/test-cases/regression/request-body-parser-xml.json
|
||||
TESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json
|
||||
TESTS+=test/test-cases/regression/rule-920120.json
|
||||
TESTS+=test/test-cases/regression/rule-920200.json
|
||||
TESTS+=test/test-cases/regression/rule-920274.json
|
||||
TESTS+=test/test-cases/regression/secaction.json
|
||||
TESTS+=test/test-cases/regression/secargumentslimit.json
|
||||
TESTS+=test/test-cases/regression/sec_component_signature.json
|
||||
TESTS+=test/test-cases/regression/secmarker.json
|
||||
TESTS+=test/test-cases/regression/secruleengine.json
|
||||
TESTS+=test/test-cases/regression/transformation-none.json
|
||||
TESTS+=test/test-cases/regression/transformations.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS_GET.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS_GET_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS_POST.json
|
||||
TESTS+=test/test-cases/regression/variable-ARGS_POST_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-AUTH_TYPE.json
|
||||
TESTS+=test/test-cases/regression/variable-DURATION.json
|
||||
TESTS+=test/test-cases/regression/variable-ENV.json
|
||||
TESTS+=test/test-cases/regression/variable-FILES_COMBINED_SIZE.json
|
||||
TESTS+=test/test-cases/regression/variable-FILES.json
|
||||
TESTS+=test/test-cases/regression/variable-FILES_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-FILES_SIZES.json
|
||||
TESTS+=test/test-cases/regression/variable-FULL_REQUEST.json
|
||||
TESTS+=test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json
|
||||
TESTS+=test/test-cases/regression/variable-GEO.json
|
||||
TESTS+=test/test-cases/regression/variable-HIGHEST_SEVERITY.json
|
||||
TESTS+=test/test-cases/regression/variable-INBOUND_DATA_ERROR.json
|
||||
TESTS+=test/test-cases/regression/variable-MATCHED_VAR.json
|
||||
TESTS+=test/test-cases/regression/variable-MATCHED_VAR_NAME.json
|
||||
TESTS+=test/test-cases/regression/variable-MATCHED_VARS.json
|
||||
TESTS+=test/test-cases/regression/variable-MATCHED_VARS_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-MODSEC_BUILD.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_FILENAME.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_NAME.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json
|
||||
TESTS+=test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json
|
||||
TESTS+=test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json
|
||||
TESTS+=test/test-cases/regression/variable-PATH_INFO.json
|
||||
TESTS+=test/test-cases/regression/variable-QUERY_STRING.json
|
||||
TESTS+=test/test-cases/regression/variable-REMOTE_ADDR.json
|
||||
TESTS+=test/test-cases/regression/variable-REMOTE_HOST.json
|
||||
TESTS+=test/test-cases/regression/variable-REMOTE_PORT.json
|
||||
TESTS+=test/test-cases/regression/variable-REMOTE_USER.json
|
||||
TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json
|
||||
TESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_BASENAME.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_BODY.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_FILENAME.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_LINE.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_METHOD.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_PROTOCOL.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_URI.json
|
||||
TESTS+=test/test-cases/regression/variable-REQUEST_URI_RAW.json
|
||||
TESTS+=test/test-cases/regression/variable-RESPONSE_BODY.json
|
||||
TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json
|
||||
TESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json
|
||||
TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS.json
|
||||
TESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json
|
||||
TESTS+=test/test-cases/regression/variable-RESPONSE_PROTOCOL.json
|
||||
TESTS+=test/test-cases/regression/variable-RULE.json
|
||||
TESTS+=test/test-cases/regression/variable-SERVER_ADDR.json
|
||||
TESTS+=test/test-cases/regression/variable-SERVER_NAME.json
|
||||
TESTS+=test/test-cases/regression/variable-SERVER_PORT.json
|
||||
TESTS+=test/test-cases/regression/variable-SESSIONID.json
|
||||
TESTS+=test/test-cases/regression/variable-STATUS.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_DAY.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_EPOCH.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_HOUR.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_MIN.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_MON.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_SEC.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_WDAY.json
|
||||
TESTS+=test/test-cases/regression/variable-TIME_YEAR.json
|
||||
TESTS+=test/test-cases/regression/variable-TX.json
|
||||
TESTS+=test/test-cases/regression/variable-UNIQUE_ID.json
|
||||
TESTS+=test/test-cases/regression/variable-URLENCODED_ERROR.json
|
||||
TESTS+=test/test-cases/regression/variable-USERID.json
|
||||
TESTS+=test/test-cases/regression/variable-variation-count.json
|
||||
TESTS+=test/test-cases/regression/variable-variation-exclusion.json
|
||||
TESTS+=test/test-cases/regression/variable-WEBAPPID.json
|
||||
TESTS+=test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json
|
||||
TESTS+=test/test-cases/regression/variable-XML.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/beginsWith.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/contains.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/containsWord.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/detectSQLi.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/detectXSS.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/endsWith.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/eq.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/ge.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/geoLookup.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/gt.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/ipMatch.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/le.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/lt.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/noMatch.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/pm.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/rx.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/rxGlobal.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/streq.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/validateByteRange.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/validateUrlEncoding.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/validateUtf8Encoding.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/verifyCC.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/verifycpf.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/verifyssn.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/verifysvnr.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/operators/within.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/base64DecodeExt.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/base64Decode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/base64Encode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/cmdLine.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/compressWhitespace.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/cssDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/escapeSeqDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/hexDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/hexEncode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/htmlEntityDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/jsDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/length.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/lowercase.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/md5.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePath.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/normalisePathWin.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/parityEven7bit.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/parityOdd7bit.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/parityZero7bit.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/removeCommentsChar.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/removeComments.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/removeNulls.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/removeWhitespace.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/replaceComments.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/replaceNulls.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/sha1.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/sqlHexDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/trim.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/trimLeft.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/trimRight.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/urlDecodeUni.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/urlEncode.json
|
||||
TESTS+=test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json
|
||||
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = modsecurity.pc
|
||||
EXTRA_DIST = modsecurity.pc.in \
|
||||
modsecurity.conf-recommended \
|
||||
unicode.mapping
|
||||
|
|
@ -1,276 +0,0 @@
|
|||
|
||||
<img src="https://github.com/SpiderLabs/ModSecurity/raw/v3/master/others/modsec.png" width="50%">
|
||||
|
||||
![Quality Assurance](https://github.com/SpiderLabs/ModSecurity/workflows/Quality%20Assurance/badge.svg)
|
||||
[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=alert_status)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=sqale_rating
|
||||
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=reliability_rating
|
||||
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=security_rating
|
||||
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
[![](https://sonarcloud.io/api/project_badges/measure?project=USHvY32Uy62L&metric=vulnerabilities
|
||||
)](https://sonarcloud.io/dashboard?id=USHvY32Uy62L)
|
||||
|
||||
|
||||
|
||||
Libmodsecurity is one component of the ModSecurity v3 project. The library
|
||||
codebase serves as an interface to ModSecurity Connectors taking in web traffic
|
||||
and applying traditional ModSecurity processing. In general, it provides the
|
||||
capability to load/interpret rules written in the ModSecurity SecRules format
|
||||
and apply them to HTTP content provided by your application via Connectors.
|
||||
|
||||
If you are looking for ModSecurity for Apache (aka ModSecurity v2.x), it is still under maintenance and available:
|
||||
[here](https://github.com/SpiderLabs/ModSecurity/tree/v2/master).
|
||||
|
||||
### What is the difference between this project and the old ModSecurity (v2.x.x)?
|
||||
|
||||
* All Apache dependencies have been removed
|
||||
* Higher performance
|
||||
* New features
|
||||
* New architecture
|
||||
|
||||
Libmodsecurity is a complete rewrite of the ModSecurity platform. When it was first devised the ModSecurity project started as just an Apache module. Over time the project has been extended, due to popular demand, to support other platforms including (but not limited to) Nginx and IIS. In order to provide for the growing demand for additional platform support, it has became necessary to remove the Apache dependencies underlying this project, making it more platform independent.
|
||||
|
||||
As a result of this goal we have rearchitected Libmodsecurity such that it is no longer dependent on the Apache web server (both at compilation and during runtime). One side effect of this is that across all platforms users can expect increased performance. Additionally, we have taken this opportunity to lay the groundwork for some new features that users have been long seeking. For example we are looking to natively support auditlogs in the JSON format, along with a host of other functionality in future versions.
|
||||
|
||||
|
||||
### It is no longer just a module.
|
||||
|
||||
The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/SpiderLabs/ModSecurity-nginx).
|
||||
|
||||
Keeping these connectors separated allows each project to have different release cycles, issues and development trees. Additionally, it means that when you install ModSecurity v3 you only get exactly what you need, no extras you won't be using.
|
||||
|
||||
# Compilation
|
||||
|
||||
Before starting the compilation process, make sure that you have all the
|
||||
dependencies in place. Read the subsection “Dependencies” for further
|
||||
information.
|
||||
|
||||
After the compilation make sure that there are no issues on your
|
||||
build/platform. We strongly recommend the utilization of the unit tests and
|
||||
regression tests. These test utilities are located under the subfolder ‘tests’.
|
||||
|
||||
As a dynamic library, don’t forget that libmodsecurity must be installed to a location (folder) where you OS will be looking for dynamic libraries.
|
||||
|
||||
|
||||
|
||||
### Unix (Linux, MacOS, FreeBSD, …)
|
||||
|
||||
On unix the project uses autotools to help the compilation process.
|
||||
|
||||
```shell
|
||||
$ ./build.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
Details on distribution specific builds can be found in our Wiki:
|
||||
[Compilation Recipes](https://github.com/SpiderLabs/ModSecurity/wiki/Compilation-recipes)
|
||||
|
||||
### Windows
|
||||
|
||||
Windows build is not ready yet.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
This library is written in C++ using the C++11 standards. It also uses Flex
|
||||
and Yacc to produce the “Sec Rules Language” parser. Other, mandatory dependencies include YAJL, as ModSecurity uses JSON for producing logs and its testing framework, libpcre (not yet mandatory) for processing regular expressions in SecRules, and libXML2 (not yet mandatory) which is used for parsing XML requests.
|
||||
|
||||
All others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. A short list of such dependencies is as follows:
|
||||
|
||||
* libinjection is needed for the operator @detectXSS and @detectSQL
|
||||
* curl is needed for the directive SecRemoteRules.
|
||||
|
||||
If those libraries are missing ModSecurity will be compiled without the support for the operator @detectXSS and the configuration directive SecRemoteRules.
|
||||
|
||||
# Library documentation
|
||||
|
||||
The library documentation is written within the code in Doxygen format. To generate this documentation, please use the doxygen utility with the provided configuration file, “doxygen.cfg”, located with the "doc/" subfolder. This will generate HTML formatted documentation including usage examples.
|
||||
|
||||
# Library utilization
|
||||
|
||||
The library provides a C++ and C interface. Some resources are currently only
|
||||
available via the C++ interface, for instance, the capability to create custom logging
|
||||
mechanism (see the regression test to check for how those logging mechanism works).
|
||||
The objective is to have both APIs (C, C++) providing the same functionality,
|
||||
if you find an aspect of the API that is missing via a particular interface, please open an issue.
|
||||
|
||||
Inside the subfolder examples, there are simple examples on how to use the API.
|
||||
Below some are illustrated:
|
||||
|
||||
### Simple example using C++
|
||||
|
||||
```c++
|
||||
using ModSecurity::ModSecurity;
|
||||
using ModSecurity::Rules;
|
||||
using ModSecurity::Transaction;
|
||||
|
||||
ModSecurity *modsec;
|
||||
ModSecurity::Rules *rules;
|
||||
|
||||
modsec = new ModSecurity();
|
||||
|
||||
rules = new Rules();
|
||||
|
||||
rules->loadFromUri(rules_file);
|
||||
|
||||
Transaction *modsecTransaction = new Transaction(modsec, rules);
|
||||
|
||||
modsecTransaction->processConnection("127.0.0.1");
|
||||
if (modsecTransaction->intervention()) {
|
||||
std::cout << "There is an intervention" << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### Simple example using C
|
||||
|
||||
```c
|
||||
#include "modsecurity/modsecurity.h"
|
||||
#include "modsecurity/transaction.h"
|
||||
|
||||
|
||||
char main_rule_uri[] = "basic_rules.conf";
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
ModSecurity *modsec = NULL;
|
||||
Transaction *transaction = NULL;
|
||||
Rules *rules = NULL;
|
||||
|
||||
modsec = msc_init();
|
||||
|
||||
rules = msc_create_rules_set();
|
||||
msc_rules_add_file(rules, main_rule_uri);
|
||||
|
||||
transaction = msc_new_transaction(modsec, rules);
|
||||
|
||||
msc_process_connection(transaction, "127.0.0.1");
|
||||
msc_process_uri(transaction, "http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3&test=args&test=test");
|
||||
msc_process_request_headers(transaction);
|
||||
msc_process_request_body(transaction);
|
||||
msc_process_response_headers(transaction);
|
||||
msc_process_response_body(transaction);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# Contributing
|
||||
|
||||
You are more than welcome to contribute to this project and look forward to growing the community around this new version of ModSecurity. Areas of interest include: New
|
||||
functionalities, fixes, bug report, support for beginning users, or anything that you
|
||||
are willing to help with.
|
||||
|
||||
## Providing patches
|
||||
|
||||
We prefer to have your patch within the GitHub infrastructure to facilitate our
|
||||
review work, and our Q.A. integration. GitHub provides excellent
|
||||
documentation on how to perform “Pull Requests”, more information available
|
||||
here: https://help.github.com/articles/using-pull-requests/
|
||||
|
||||
Please respect the coding style. Pull requests can include various commits, so
|
||||
provide one fix or one piece of functionality per commit. Please do not change anything outside
|
||||
the scope of your target work (e.g. coding style in a function that you have
|
||||
passed by). For further information about the coding style used in this
|
||||
project, please check: https://www.chromium.org/blink/coding-style
|
||||
|
||||
Provides explanative commit messages. Your first line should give the highlights of your
|
||||
patch, 3rd and on give a more detailed explanation/technical details about your
|
||||
patch. Patch explanation is valuable during the review process.
|
||||
|
||||
### Don’t know where to start?
|
||||
|
||||
Within our code there are various items marked as TODO or FIXME that may need
|
||||
your attention. Check the list of items by performing a grep:
|
||||
|
||||
```
|
||||
$ cd /path/to/modsecurity-nginx
|
||||
$ egrep -Rin "TODO|FIXME" -R *
|
||||
```
|
||||
|
||||
A TODO list is also available as part of the Doxygen documentation.
|
||||
|
||||
### Testing your patch
|
||||
|
||||
Along with the manual testing, we strongly recommend you to use the our
|
||||
regression tests and unit tests. If you have implemented an operator, don’t
|
||||
forget to create unit tests for it. If you implement anything else, it is encouraged that you develop complimentary regression tests for it.
|
||||
|
||||
The regression test and unit test utilities are native and do not demand any
|
||||
external tool or script, although you need to fetch the test cases from other
|
||||
repositories, as they are shared with other versions of ModSecurity, those
|
||||
others repositories git submodules. To fetch the submodules repository and run
|
||||
the utilities, follow the commands listed below:
|
||||
|
||||
```shell
|
||||
$ cd /path/to/your/ModSecurity
|
||||
$ git submodule foreach git pull
|
||||
$ cd test
|
||||
$ ./regression-tests
|
||||
$ ./unit-tests
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
|
||||
Before start the debugging process, make sure of where your bug is. The problem
|
||||
could be on your connector or in libmodsecurity. In order to identify where the
|
||||
bug is, it is recommended that you develop a regression test that mimics the
|
||||
scenario where the bug is happening. If the bug is reproducible with the
|
||||
regression-test utility, then it will be far simpler to debug and ensure that it never occurs again. On Linux it is
|
||||
recommended that anyone undertaking debugging utilize gdb and/or valgrind as needed.
|
||||
|
||||
During the configuration/compilation time, you may want to disable the compiler
|
||||
optimization making your “back traces” populated with readable data. Use the
|
||||
CFLAGS to disable the compilation optimization parameters:
|
||||
|
||||
```shell
|
||||
$ export CFLAGS="-g -O0"
|
||||
$ ./build.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
```
|
||||
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
If you are facing a configuration issue or something is not working as you
|
||||
expected to be, please use the ModSecurity user’s mailing list. Issues on GitHub
|
||||
are also welcomed, but we prefer to have user ask questions on the mailing list first so that you can reach an entire community. Also don’t forget to look for existing issues before open a new one.
|
||||
|
||||
If you are going to open a new issue on GitHub, don’t forget to tell us the
|
||||
version of your libmodsecurity and the version of a specific connector if there
|
||||
is one.
|
||||
|
||||
|
||||
### Security issue
|
||||
|
||||
Please do not make public any security issue. Contact us at:
|
||||
security@modsecurity.org reporting the issue. Once the problem is fixed your
|
||||
credit will be given.
|
||||
|
||||
## Feature request
|
||||
|
||||
We are open to discussing any new feature request with the community via the mailing lists. You can alternativly,
|
||||
feel free to open GitHub issues requesting new features. Before opening a
|
||||
new issue, please check if there is one already opened on the same topic.
|
||||
|
||||
## Bindings
|
||||
|
||||
The libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are two notable projects maintained by the community:
|
||||
* Python - https://github.com/actions-security/pymodsecurity
|
||||
* Varnish - https://github.com/xdecock/vmod-modsecurity
|
||||
|
||||
## Packaging
|
||||
|
||||
Having our packages in distros on time is a desire that we have, so let us know
|
||||
if there is anything we can do to facilitate your work as a packager.
|
||||
|
||||
## Sponsor Note
|
||||
|
||||
Development of ModSecurity is sponsored by Trustwave. Sponsorship will end July 1, 2024. Additional information can be found here https://www.trustwave.com/en-us/resources/security-resources/software-updates/end-of-sale-and-trustwave-support-for-modsecurity-web-application-firewall/
|
|
@ -1,9 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
The latest versions of both v2.9.x and v3.0.x are supported.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
For information on how to report a security issue, please see https://github.com/SpiderLabs/ModSecurity#security-issue
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
rm -rf autom4te.cache
|
||||
rm -f aclocal.m4
|
||||
case `uname` in Darwin*) glibtoolize --force --copy ;;
|
||||
*) libtoolize --force --copy ;; esac
|
||||
autoreconf --install
|
||||
autoheader
|
||||
automake --add-missing --foreign --copy --force-missing
|
||||
autoconf --force
|
||||
rm -rf autom4te.cache
|
||||
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
# ============================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||
# ============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++11
|
||||
# standard; if necessary, add switches to CXXFLAGS to enable support.
|
||||
#
|
||||
# The first argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The second argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline C++11 support is required and that the macro
|
||||
# should error out if no mode with that support is found. If specified
|
||||
# 'optional', then configuration proceeds regardless, after defining
|
||||
# HAVE_CXX11 if and only if a supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 12
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
struct Base {
|
||||
virtual void f() {}
|
||||
};
|
||||
struct Child : public Base {
|
||||
virtual void f() override {}
|
||||
};
|
||||
|
||||
typedef check<check<bool>> right_angle_brackets;
|
||||
|
||||
int a;
|
||||
decltype(a) b;
|
||||
|
||||
typedef check<int> check_type;
|
||||
check_type c;
|
||||
check_type&& cr = static_cast<check_type&&>(c);
|
||||
|
||||
auto d = a;
|
||||
auto l = [](){};
|
||||
// Prevent Clang error: unused variable 'l' [-Werror,-Wunused-variable]
|
||||
struct use_l { use_l() { l(); } };
|
||||
|
||||
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
|
||||
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this
|
||||
namespace test_template_alias_sfinae {
|
||||
struct foo {};
|
||||
|
||||
template<typename T>
|
||||
using member = typename T::member_type;
|
||||
|
||||
template<typename T>
|
||||
void func(...) {}
|
||||
|
||||
template<typename T>
|
||||
void func(member<T>*) {}
|
||||
|
||||
void test();
|
||||
|
||||
void test() {
|
||||
func<foo>(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for C++11 attribute support
|
||||
void noret [[noreturn]] () { throw 0; }
|
||||
]])
|
||||
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
|
||||
m4_if([$1], [], [],
|
||||
[$1], [ext], [],
|
||||
[$1], [noext], [],
|
||||
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
|
||||
ax_cv_cxx_compile_cxx11,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[ax_cv_cxx_compile_cxx11=yes],
|
||||
[ax_cv_cxx_compile_cxx11=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
|
||||
ac_success=yes
|
||||
fi
|
||||
|
||||
m4_if([$1], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=gnu++11 -std=gnu++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$1], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
dnl HP's aCC needs +std=c++11 according to:
|
||||
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
|
||||
for switch in -std=c++11 -std=c++0x +std=c++11; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx11_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
|
||||
fi
|
||||
else
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX11=0
|
||||
AC_MSG_NOTICE([No compiler with C++11 support was found])
|
||||
else
|
||||
HAVE_CXX11=1
|
||||
AC_DEFINE(HAVE_CXX11,1,
|
||||
[define if the compiler supports basic C++11 syntax])
|
||||
fi
|
||||
|
||||
AC_SUBST(HAVE_CXX11)
|
||||
fi
|
||||
])
|
|
@ -1,533 +0,0 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR])
|
||||
# DX_DOXYGEN_FEATURE(ON|OFF)
|
||||
# DX_DOT_FEATURE(ON|OFF)
|
||||
# DX_HTML_FEATURE(ON|OFF)
|
||||
# DX_CHM_FEATURE(ON|OFF)
|
||||
# DX_CHI_FEATURE(ON|OFF)
|
||||
# DX_MAN_FEATURE(ON|OFF)
|
||||
# DX_RTF_FEATURE(ON|OFF)
|
||||
# DX_XML_FEATURE(ON|OFF)
|
||||
# DX_PDF_FEATURE(ON|OFF)
|
||||
# DX_PS_FEATURE(ON|OFF)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# The DX_*_FEATURE macros control the default setting for the given
|
||||
# Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for
|
||||
# generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML
|
||||
# help (for MS users), 'CHI' for generating a seperate .chi file by the
|
||||
# .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate
|
||||
# output formats. The environment variable DOXYGEN_PAPER_SIZE may be
|
||||
# specified to override the default 'a4wide' paper size.
|
||||
#
|
||||
# By default, HTML, PDF and PS documentation is generated as this seems to
|
||||
# be the most popular and portable combination. MAN pages created by
|
||||
# Doxygen are usually problematic, though by picking an appropriate subset
|
||||
# and doing some massaging they might be better than nothing. CHM and RTF
|
||||
# are specific for MS (note that you can't generate both HTML and CHM at
|
||||
# the same time). The XML is rather useless unless you apply specialized
|
||||
# post-processing to it.
|
||||
#
|
||||
# The macros mainly control the default state of the feature. The use can
|
||||
# override the default by specifying --enable or --disable. The macros
|
||||
# ensure that contradictory flags are not given (e.g.,
|
||||
# --enable-doxygen-html and --enable-doxygen-chm,
|
||||
# --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each
|
||||
# feature will be automatically disabled (with a warning) if the required
|
||||
# programs are missing.
|
||||
#
|
||||
# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
|
||||
# with the following parameters: a one-word name for the project for use
|
||||
# as a filename base etc., an optional configuration file name (the
|
||||
# default is 'Doxyfile', the same as Doxygen's default), and an optional
|
||||
# output directory name (the default is 'doxygen-doc').
|
||||
#
|
||||
# Automake Support
|
||||
#
|
||||
# The following is a template aminclude.am file for use with Automake.
|
||||
# Make targets and variables values are controlled by the various
|
||||
# DX_COND_* conditionals set by autoconf.
|
||||
#
|
||||
# The provided targets are:
|
||||
#
|
||||
# doxygen-doc: Generate all doxygen documentation.
|
||||
#
|
||||
# doxygen-run: Run doxygen, which will generate some of the
|
||||
# documentation (HTML, CHM, CHI, MAN, RTF, XML)
|
||||
# but will not do the post processing required
|
||||
# for the rest of it (PS, PDF, and some MAN).
|
||||
#
|
||||
# doxygen-man: Rename some doxygen generated man pages.
|
||||
#
|
||||
# doxygen-ps: Generate doxygen PostScript documentation.
|
||||
#
|
||||
# doxygen-pdf: Generate doxygen PDF documentation.
|
||||
#
|
||||
# Note that by default these are not integrated into the automake targets.
|
||||
# If doxygen is used to generate man pages, you can achieve this
|
||||
# integration by setting man3_MANS to the list of man pages generated and
|
||||
# then adding the dependency:
|
||||
#
|
||||
# $(man3_MANS): doxygen-doc
|
||||
#
|
||||
# This will cause make to run doxygen and generate all the documentation.
|
||||
#
|
||||
# The following variable is intended for use in Makefile.am:
|
||||
#
|
||||
# DX_CLEANFILES = everything to clean.
|
||||
#
|
||||
# Then add this variable to MOSTLYCLEANFILES.
|
||||
#
|
||||
# ----- begin aminclude.am -------------------------------------
|
||||
#
|
||||
# ## --------------------------------- ##
|
||||
# ## Format-independent Doxygen rules. ##
|
||||
# ## --------------------------------- ##
|
||||
#
|
||||
# if DX_COND_doc
|
||||
#
|
||||
# ## ------------------------------- ##
|
||||
# ## Rules specific for HTML output. ##
|
||||
# ## ------------------------------- ##
|
||||
#
|
||||
# if DX_COND_html
|
||||
#
|
||||
# DX_CLEAN_HTML = @DX_DOCDIR@/html
|
||||
#
|
||||
# endif DX_COND_html
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for CHM output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_chm
|
||||
#
|
||||
# DX_CLEAN_CHM = @DX_DOCDIR@/chm
|
||||
#
|
||||
# if DX_COND_chi
|
||||
#
|
||||
# DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
|
||||
#
|
||||
# endif DX_COND_chi
|
||||
#
|
||||
# endif DX_COND_chm
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for MAN output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_man
|
||||
#
|
||||
# DX_CLEAN_MAN = @DX_DOCDIR@/man
|
||||
#
|
||||
# endif DX_COND_man
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for RTF output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_rtf
|
||||
#
|
||||
# DX_CLEAN_RTF = @DX_DOCDIR@/rtf
|
||||
#
|
||||
# endif DX_COND_rtf
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for XML output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_xml
|
||||
#
|
||||
# DX_CLEAN_XML = @DX_DOCDIR@/xml
|
||||
#
|
||||
# endif DX_COND_xml
|
||||
#
|
||||
# ## ----------------------------- ##
|
||||
# ## Rules specific for PS output. ##
|
||||
# ## ----------------------------- ##
|
||||
#
|
||||
# if DX_COND_ps
|
||||
#
|
||||
# DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
|
||||
#
|
||||
# DX_PS_GOAL = doxygen-ps
|
||||
#
|
||||
# doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
|
||||
#
|
||||
# @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
# cd @DX_DOCDIR@/latex; \
|
||||
# rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
# $(DX_LATEX) refman.tex; \
|
||||
# $(MAKEINDEX_PATH) refman.idx; \
|
||||
# $(DX_LATEX) refman.tex; \
|
||||
# countdown=5; \
|
||||
# while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
|
||||
# refman.log > /dev/null 2>&1 \
|
||||
# && test $$countdown -gt 0; do \
|
||||
# $(DX_LATEX) refman.tex; \
|
||||
# countdown=`expr $$countdown - 1`; \
|
||||
# done; \
|
||||
# $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
|
||||
#
|
||||
# endif DX_COND_ps
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for PDF output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_pdf
|
||||
#
|
||||
# DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
|
||||
#
|
||||
# DX_PDF_GOAL = doxygen-pdf
|
||||
#
|
||||
# doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
|
||||
#
|
||||
# @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
# cd @DX_DOCDIR@/latex; \
|
||||
# rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
# $(DX_PDFLATEX) refman.tex; \
|
||||
# $(DX_MAKEINDEX) refman.idx; \
|
||||
# $(DX_PDFLATEX) refman.tex; \
|
||||
# countdown=5; \
|
||||
# while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
|
||||
# refman.log > /dev/null 2>&1 \
|
||||
# && test $$countdown -gt 0; do \
|
||||
# $(DX_PDFLATEX) refman.tex; \
|
||||
# countdown=`expr $$countdown - 1`; \
|
||||
# done; \
|
||||
# mv refman.pdf ../@PACKAGE@.pdf
|
||||
#
|
||||
# endif DX_COND_pdf
|
||||
#
|
||||
# ## ------------------------------------------------- ##
|
||||
# ## Rules specific for LaTeX (shared for PS and PDF). ##
|
||||
# ## ------------------------------------------------- ##
|
||||
#
|
||||
# if DX_COND_latex
|
||||
#
|
||||
# DX_CLEAN_LATEX = @DX_DOCDIR@/latex
|
||||
#
|
||||
# endif DX_COND_latex
|
||||
#
|
||||
# .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
#
|
||||
# .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
#
|
||||
# doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
#
|
||||
# doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
#
|
||||
# @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
|
||||
# rm -rf @DX_DOCDIR@
|
||||
# $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
|
||||
# echo Timestamp >$@
|
||||
#
|
||||
# DX_CLEANFILES = \
|
||||
# @DX_DOCDIR@/@PACKAGE@.tag \
|
||||
# -r \
|
||||
# $(DX_CLEAN_HTML) \
|
||||
# $(DX_CLEAN_CHM) \
|
||||
# $(DX_CLEAN_CHI) \
|
||||
# $(DX_CLEAN_MAN) \
|
||||
# $(DX_CLEAN_RTF) \
|
||||
# $(DX_CLEAN_XML) \
|
||||
# $(DX_CLEAN_PS) \
|
||||
# $(DX_CLEAN_PDF) \
|
||||
# $(DX_CLEAN_LATEX)
|
||||
#
|
||||
# endif DX_COND_doc
|
||||
#
|
||||
# ----- end aminclude.am ---------------------------------------
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 13
|
||||
|
||||
## ----------##
|
||||
## Defaults. ##
|
||||
## ----------##
|
||||
|
||||
DX_ENV=""
|
||||
AC_DEFUN([DX_FEATURE_doc], ON)
|
||||
AC_DEFUN([DX_FEATURE_dot], OFF)
|
||||
AC_DEFUN([DX_FEATURE_man], OFF)
|
||||
AC_DEFUN([DX_FEATURE_html], ON)
|
||||
AC_DEFUN([DX_FEATURE_chm], OFF)
|
||||
AC_DEFUN([DX_FEATURE_chi], OFF)
|
||||
AC_DEFUN([DX_FEATURE_rtf], OFF)
|
||||
AC_DEFUN([DX_FEATURE_xml], OFF)
|
||||
AC_DEFUN([DX_FEATURE_pdf], ON)
|
||||
AC_DEFUN([DX_FEATURE_ps], ON)
|
||||
|
||||
## --------------- ##
|
||||
## Private macros. ##
|
||||
## --------------- ##
|
||||
|
||||
# DX_ENV_APPEND(VARIABLE, VALUE)
|
||||
# ------------------------------
|
||||
# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
|
||||
AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
|
||||
|
||||
# DX_DIRNAME_EXPR
|
||||
# ---------------
|
||||
# Expand into a shell expression prints the directory part of a path.
|
||||
AC_DEFUN([DX_DIRNAME_EXPR],
|
||||
[[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
|
||||
|
||||
# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
|
||||
# -------------------------------------
|
||||
# Expands according to the M4 (static) status of the feature.
|
||||
AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
|
||||
|
||||
# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
|
||||
# ----------------------------------
|
||||
# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
|
||||
AC_DEFUN([DX_REQUIRE_PROG], [
|
||||
AC_PATH_TOOL([$1], [$2])
|
||||
if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
|
||||
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
|
||||
AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
|
||||
fi
|
||||
])
|
||||
|
||||
# DX_TEST_FEATURE(FEATURE)
|
||||
# ------------------------
|
||||
# Expand to a shell expression testing whether the feature is active.
|
||||
AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
|
||||
|
||||
# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
|
||||
# -------------------------------------------------
|
||||
# Verify that a required features has the right state before trying to turn on
|
||||
# the DX_CURRENT_FEATURE.
|
||||
AC_DEFUN([DX_CHECK_DEPEND], [
|
||||
test "$DX_FLAG_$1" = "$2" \
|
||||
|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
|
||||
requires, contradicts) doxygen-DX_CURRENT_FEATURE])
|
||||
])
|
||||
|
||||
# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
|
||||
# ----------------------------------------------------------
|
||||
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
|
||||
AC_DEFUN([DX_CLEAR_DEPEND], [
|
||||
test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
|
||||
])
|
||||
|
||||
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
|
||||
# CHECK_DEPEND, CLEAR_DEPEND,
|
||||
# REQUIRE, DO-IF-ON, DO-IF-OFF)
|
||||
# --------------------------------------------
|
||||
# Parse the command-line option controlling a feature. CHECK_DEPEND is called
|
||||
# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
|
||||
# otherwise CLEAR_DEPEND is called to turn off the default state if a required
|
||||
# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
|
||||
# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
|
||||
# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
|
||||
AC_DEFUN([DX_ARG_ABLE], [
|
||||
AC_DEFUN([DX_CURRENT_FEATURE], [$1])
|
||||
AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
|
||||
AC_ARG_ENABLE(doxygen-$1,
|
||||
[AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
|
||||
[--enable-doxygen-$1]),
|
||||
DX_IF_FEATURE([$1], [don't $2], [$2]))],
|
||||
[
|
||||
case "$enableval" in
|
||||
#(
|
||||
y|Y|yes|Yes|YES)
|
||||
AC_SUBST([DX_FLAG_$1], 1)
|
||||
$3
|
||||
;; #(
|
||||
n|N|no|No|NO)
|
||||
AC_SUBST([DX_FLAG_$1], 0)
|
||||
;; #(
|
||||
*)
|
||||
AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
|
||||
;;
|
||||
esac
|
||||
], [
|
||||
AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
|
||||
$4
|
||||
])
|
||||
if DX_TEST_FEATURE([$1]); then
|
||||
$5
|
||||
:
|
||||
fi
|
||||
AM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1]))
|
||||
if DX_TEST_FEATURE([$1]); then
|
||||
$6
|
||||
:
|
||||
else
|
||||
$7
|
||||
:
|
||||
fi
|
||||
])
|
||||
|
||||
## -------------- ##
|
||||
## Public macros. ##
|
||||
## -------------- ##
|
||||
|
||||
# DX_XXX_FEATURE(DEFAULT_STATE)
|
||||
# -----------------------------
|
||||
AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
|
||||
AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])])
|
||||
AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
|
||||
AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
|
||||
AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
|
||||
AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
|
||||
AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
|
||||
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
|
||||
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
|
||||
AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
|
||||
AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
|
||||
|
||||
# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
|
||||
# ---------------------------------------------------------
|
||||
# PROJECT also serves as the base name for the documentation files.
|
||||
# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
|
||||
AC_DEFUN([DX_INIT_DOXYGEN], [
|
||||
|
||||
# Files:
|
||||
AC_SUBST([DX_PROJECT], [$1])
|
||||
AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
|
||||
AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
|
||||
|
||||
# Environment variables used inside doxygen.cfg:
|
||||
DX_ENV_APPEND(SRCDIR, $srcdir)
|
||||
DX_ENV_APPEND(PROJECT, $DX_PROJECT)
|
||||
DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
|
||||
DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
|
||||
|
||||
# Doxygen itself:
|
||||
DX_ARG_ABLE(doc, [generate any doxygen documentation],
|
||||
[],
|
||||
[],
|
||||
[DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
|
||||
DX_REQUIRE_PROG([DX_PERL], perl)],
|
||||
[DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
|
||||
|
||||
# Dot for graphics:
|
||||
DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_DOT], dot)],
|
||||
[DX_ENV_APPEND(HAVE_DOT, YES)
|
||||
DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
|
||||
[DX_ENV_APPEND(HAVE_DOT, NO)])
|
||||
|
||||
# Man pages generation:
|
||||
DX_ARG_ABLE(man, [generate doxygen manual pages],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_MAN, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_MAN, NO)])
|
||||
|
||||
# RTF file generation:
|
||||
DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_RTF, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_RTF, NO)])
|
||||
|
||||
# XML file generation:
|
||||
DX_ARG_ABLE(xml, [generate doxygen XML documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_XML, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_XML, NO)])
|
||||
|
||||
# (Compressed) HTML help generation:
|
||||
DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_HHC], hhc)],
|
||||
[DX_ENV_APPEND(HHC_PATH, $DX_HHC)
|
||||
DX_ENV_APPEND(GENERATE_HTML, YES)
|
||||
DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
|
||||
|
||||
# Seperate CHI file generation.
|
||||
DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
|
||||
[DX_CHECK_DEPEND(chm, 1)],
|
||||
[DX_CLEAR_DEPEND(chm, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_CHI, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_CHI, NO)])
|
||||
|
||||
# Plain HTML pages generation:
|
||||
DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
|
||||
[DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_HTML, YES)],
|
||||
[DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
|
||||
|
||||
# PostScript file generation:
|
||||
DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_LATEX], latex)
|
||||
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
|
||||
DX_REQUIRE_PROG([DX_DVIPS], dvips)
|
||||
DX_REQUIRE_PROG([DX_EGREP], egrep)])
|
||||
|
||||
# PDF file generation:
|
||||
DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
|
||||
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
|
||||
DX_REQUIRE_PROG([DX_EGREP], egrep)])
|
||||
|
||||
# LaTeX generation for PS and/or PDF:
|
||||
AM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf))
|
||||
if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
|
||||
DX_ENV_APPEND(GENERATE_LATEX, YES)
|
||||
else
|
||||
DX_ENV_APPEND(GENERATE_LATEX, NO)
|
||||
fi
|
||||
|
||||
# Paper size for PS and/or PDF:
|
||||
AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
|
||||
[a4wide (default), a4, letter, legal or executive])
|
||||
case "$DOXYGEN_PAPER_SIZE" in
|
||||
#(
|
||||
"")
|
||||
AC_SUBST(DOXYGEN_PAPER_SIZE, "")
|
||||
;; #(
|
||||
a4wide|a4|letter|legal|executive)
|
||||
DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
|
||||
;; #(
|
||||
*)
|
||||
AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
|
||||
;;
|
||||
esac
|
||||
|
||||
#For debugging:
|
||||
#echo DX_FLAG_doc=$DX_FLAG_doc
|
||||
#echo DX_FLAG_dot=$DX_FLAG_dot
|
||||
#echo DX_FLAG_man=$DX_FLAG_man
|
||||
#echo DX_FLAG_html=$DX_FLAG_html
|
||||
#echo DX_FLAG_chm=$DX_FLAG_chm
|
||||
#echo DX_FLAG_chi=$DX_FLAG_chi
|
||||
#echo DX_FLAG_rtf=$DX_FLAG_rtf
|
||||
#echo DX_FLAG_xml=$DX_FLAG_xml
|
||||
#echo DX_FLAG_pdf=$DX_FLAG_pdf
|
||||
#echo DX_FLAG_ps=$DX_FLAG_ps
|
||||
#echo DX_ENV=$DX_ENV
|
||||
])
|
|
@ -1,236 +0,0 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off)
|
||||
# AX_VALGRIND_CHECK()
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows
|
||||
# running `make check` under a variety of Valgrind tools to check for
|
||||
# memory and threading errors.
|
||||
#
|
||||
# Defines VALGRIND_CHECK_RULES which should be substituted in your
|
||||
# Makefile; and $enable_valgrind which can be used in subsequent configure
|
||||
# output. VALGRIND_ENABLED is defined and substituted, and corresponds to
|
||||
# the value of the --enable-valgrind option, which defaults to being
|
||||
# enabled if Valgrind is installed and disabled otherwise. Individual
|
||||
# Valgrind tools can be disabled via --disable-valgrind-<tool>, the
|
||||
# default is configurable via the AX_VALGRIND_DFLT command or is to use
|
||||
# all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT
|
||||
# calls must be made before the call to AX_VALGRIND_CHECK.
|
||||
#
|
||||
# If unit tests are written using a shell script and automake's
|
||||
# LOG_COMPILER system, the $(VALGRIND) variable can be used within the
|
||||
# shell scripts to enable Valgrind, as described here:
|
||||
#
|
||||
# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html
|
||||
#
|
||||
# Usage example:
|
||||
#
|
||||
# configure.ac:
|
||||
#
|
||||
# AX_VALGRIND_DFLT([sgcheck], [off])
|
||||
# AX_VALGRIND_CHECK
|
||||
#
|
||||
# Makefile.am:
|
||||
#
|
||||
# @VALGRIND_CHECK_RULES@
|
||||
# VALGRIND_SUPPRESSIONS_FILES = my-project.supp
|
||||
# EXTRA_DIST = my-project.supp
|
||||
#
|
||||
# This results in a "check-valgrind" rule being added to any Makefile.am
|
||||
# which includes "@VALGRIND_CHECK_RULES@" (assuming the module has been
|
||||
# configured with --enable-valgrind). Running `make check-valgrind` in
|
||||
# that directory will run the module's test suite (`make check`) once for
|
||||
# each of the available Valgrind tools (out of memcheck, helgrind and drd)
|
||||
# while the sgcheck will be skipped unless enabled again on the
|
||||
# commandline with --enable-valgrind-sgcheck. The results for each check
|
||||
# will be output to test-suite-$toolname.log. The target will succeed if
|
||||
# there are zero errors and fail otherwise.
|
||||
#
|
||||
# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in
|
||||
# memcheck, helgrind, drd and sgcheck. These are useful because often only
|
||||
# some of those tools can be ran cleanly on a codebase.
|
||||
#
|
||||
# The macro supports running with and without libtool.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016 Philip Withnall <philip.withnall@collabora.co.uk>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 13
|
||||
|
||||
dnl Configured tools
|
||||
m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]])
|
||||
m4_set_add_all([valgrind_exp_tool_set], [sgcheck])
|
||||
m4_foreach([vgtool], [valgrind_tool_list],
|
||||
[m4_define([en_dflt_valgrind_]vgtool, [on])])
|
||||
|
||||
AC_DEFUN([AX_VALGRIND_DFLT],[
|
||||
m4_define([en_dflt_valgrind_$1], [$2])
|
||||
])dnl
|
||||
|
||||
AC_DEFUN([AX_VALGRIND_CHECK],[
|
||||
dnl Check for --enable-valgrind
|
||||
AC_ARG_ENABLE([valgrind],
|
||||
[AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])],
|
||||
[enable_valgrind=$enableval],[enable_valgrind=])
|
||||
|
||||
AS_IF([test "$enable_valgrind" != "no"],[
|
||||
# Check for Valgrind.
|
||||
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind])
|
||||
AS_IF([test "$VALGRIND" = ""],[
|
||||
AS_IF([test "$enable_valgrind" = "yes"],[
|
||||
AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind])
|
||||
],[
|
||||
enable_valgrind=no
|
||||
])
|
||||
],[
|
||||
enable_valgrind=yes
|
||||
])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"])
|
||||
AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind])
|
||||
|
||||
# Check for Valgrind tools we care about.
|
||||
[valgrind_enabled_tools=]
|
||||
m4_foreach([vgtool],[valgrind_tool_list],[
|
||||
AC_ARG_ENABLE([valgrind-]vgtool,
|
||||
m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl
|
||||
[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl
|
||||
[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]),
|
||||
[enable_valgrind_]vgtool[=$enableval],
|
||||
[enable_valgrind_]vgtool[=])
|
||||
AS_IF([test "$enable_valgrind" = "no"],[
|
||||
enable_valgrind_]vgtool[=no],
|
||||
[test "$enable_valgrind_]vgtool[" ]dnl
|
||||
m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[
|
||||
AC_CACHE_CHECK([for Valgrind tool ]vgtool,
|
||||
[ax_cv_valgrind_tool_]vgtool,[
|
||||
ax_cv_valgrind_tool_]vgtool[=no
|
||||
m4_set_contains([valgrind_exp_tool_set],vgtool,
|
||||
[m4_define([vgtoolx],[exp-]vgtool)],
|
||||
[m4_define([vgtoolx],vgtool)])
|
||||
AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[
|
||||
ax_cv_valgrind_tool_]vgtool[=yes
|
||||
])
|
||||
])
|
||||
AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[
|
||||
AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[
|
||||
AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool)
|
||||
],[
|
||||
enable_valgrind_]vgtool[=no
|
||||
])
|
||||
],[
|
||||
enable_valgrind_]vgtool[=yes
|
||||
])
|
||||
])
|
||||
AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[
|
||||
valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])["
|
||||
])
|
||||
AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool)
|
||||
])
|
||||
AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["])
|
||||
AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools])
|
||||
|
||||
[VALGRIND_CHECK_RULES='
|
||||
# Valgrind check
|
||||
#
|
||||
# Optional:
|
||||
# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions
|
||||
# files to load. (Default: empty)
|
||||
# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools.
|
||||
# (Default: --num-callers=30)
|
||||
# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of:
|
||||
# memcheck, helgrind, drd, sgcheck). (Default: various)
|
||||
|
||||
# Optional variables
|
||||
VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES))
|
||||
VALGRIND_FLAGS ?= --num-callers=30
|
||||
VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no
|
||||
VALGRIND_helgrind_FLAGS ?= --history-level=approx
|
||||
VALGRIND_drd_FLAGS ?=
|
||||
VALGRIND_sgcheck_FLAGS ?=
|
||||
|
||||
# Internal use
|
||||
valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools)))
|
||||
|
||||
valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS)
|
||||
valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS)
|
||||
valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS)
|
||||
valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS)
|
||||
|
||||
valgrind_quiet = $(valgrind_quiet_$(V))
|
||||
valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY))
|
||||
valgrind_quiet_0 = --quiet
|
||||
valgrind_v_use = $(valgrind_v_use_$(V))
|
||||
valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY))
|
||||
valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%,%,$''@):;
|
||||
|
||||
# Support running with and without libtool.
|
||||
ifneq ($(LIBTOOL),)
|
||||
valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute
|
||||
else
|
||||
valgrind_lt =
|
||||
endif
|
||||
|
||||
# Use recursive makes in order to ignore errors during check
|
||||
check-valgrind:
|
||||
ifeq ($(VALGRIND_ENABLED),yes)
|
||||
-$(A''M_V_at)$(foreach tool,$(valgrind_enabled_tools), \
|
||||
$(MAKE) $(AM_MAKEFLAGS) -k check-valgrind-$(tool); \
|
||||
)
|
||||
else
|
||||
@echo "Need to reconfigure with --enable-valgrind"
|
||||
endif
|
||||
|
||||
# Valgrind running
|
||||
VALGRIND_TESTS_ENVIRONMENT = \
|
||||
$(TESTS_ENVIRONMENT) \
|
||||
env VALGRIND=$(VALGRIND) \
|
||||
G_SLICE=always-malloc,debug-blocks \
|
||||
G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly
|
||||
|
||||
VALGRIND_LOG_COMPILER = test/test-suite.sh $(VALGRIND_SUPPRESSIONS) $(VALGRIND_FLAGS)
|
||||
# $(valgrind_lt) \
|
||||
# $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS)
|
||||
|
||||
define valgrind_tool_rule =
|
||||
check-valgrind-$(1):
|
||||
ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes)
|
||||
$$(valgrind_v_use)$$(MAKE) check-TESTS \
|
||||
TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \
|
||||
LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \
|
||||
LOG_FLAGS="$$(valgrind_$(1)_flags)" \
|
||||
TEST_SUITE_LOG=test-suite-$(1).log
|
||||
else ifeq ($$(VALGRIND_ENABLED),yes)
|
||||
@echo "Need to reconfigure with --enable-valgrind-$(1)"
|
||||
else
|
||||
@echo "Need to reconfigure with --enable-valgrind"
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool))))
|
||||
|
||||
A''M_DISTCHECK_CONFIGURE_FLAGS ?=
|
||||
A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind
|
||||
|
||||
MOSTLYCLEANFILES ?=
|
||||
MOSTLYCLEANFILES += $(valgrind_log_files)
|
||||
|
||||
.PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools))
|
||||
']
|
||||
|
||||
AC_SUBST([VALGRIND_CHECK_RULES])
|
||||
m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])])
|
||||
])
|
|
@ -1,131 +0,0 @@
|
|||
dnl Check for CURL Libraries
|
||||
dnl CHECK_CURL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
dnl Sets:
|
||||
dnl CURL_CFLAGS
|
||||
dnl CURL_LIBS
|
||||
|
||||
CURL_CONFIG=""
|
||||
CURL_VERSION=""
|
||||
CURL_CPPFLAGS=""
|
||||
CURL_CFLAGS=""
|
||||
CURL_LDFLAGS=""
|
||||
CURL_LDADD=""
|
||||
CURL_MIN_VERSION="7.15.1"
|
||||
|
||||
AC_DEFUN([CHECK_CURL], [
|
||||
|
||||
|
||||
AC_ARG_WITH(
|
||||
curl,
|
||||
[AS_HELP_STRING([--with-curl=PATH],[Path to curl prefix or config script])],
|
||||
[test_paths="${with_curl}"],
|
||||
[test_paths="/usr/local/libcurl /usr/local/curl /usr/local /opt/libcurl /opt/curl /opt /usr"])
|
||||
|
||||
AC_MSG_CHECKING([for libcurl config script])
|
||||
|
||||
for x in ${test_paths}; do
|
||||
dnl # Determine if the script was specified and use it directly
|
||||
if test ! -d "$x" -a -e "$x"; then
|
||||
CURL_CONFIG=$x
|
||||
curl_path="no"
|
||||
break
|
||||
fi
|
||||
|
||||
dnl # Try known config script names/locations
|
||||
for CURL_CONFIG in curl-config; do
|
||||
if test -e "${x}/bin/${CURL_CONFIG}"; then
|
||||
curl_path="${x}/bin"
|
||||
break
|
||||
elif test -e "${x}/${CURL_CONFIG}"; then
|
||||
curl_path="${x}"
|
||||
break
|
||||
else
|
||||
curl_path=""
|
||||
fi
|
||||
done
|
||||
if test -n "$curl_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -n "${curl_path}"; then
|
||||
if test "${curl_path}" != "no"; then
|
||||
CURL_CONFIG="${curl_path}/${CURL_CONFIG}"
|
||||
fi
|
||||
AC_MSG_RESULT([${CURL_CONFIG}])
|
||||
CURL_VERSION=`${CURL_CONFIG} --version | sed 's/^[[^0-9]][[^[:space:]]][[^[:space:]]]*[[[:space:]]]*//' | tr '\r\n' ' '`
|
||||
if test ! -z "${CURL_VERSION}"; then AC_MSG_NOTICE(curl VERSION: $CURL_VERSION); fi
|
||||
CURL_CFLAGS="`${CURL_CONFIG} --cflags`"
|
||||
if test ! -z "${CURL_CFLAGS}"; then AC_MSG_NOTICE(curl CFLAGS: $CURL_CFLAGS); fi
|
||||
CURL_LDADD="`${CURL_CONFIG} --libs`"
|
||||
if test ! -z "${CURL_CONFIG}"; then AC_MSG_NOTICE(curl LDADD: $CURL_LIBS); fi
|
||||
|
||||
dnl # Check version is ok
|
||||
AC_MSG_CHECKING([if libcurl is at least v${CURL_MIN_VERSION}])
|
||||
curl_min_ver=`echo ${CURL_MIN_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'`
|
||||
curl_ver=`echo ${CURL_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'`
|
||||
if test "$curl_min_ver" -le "$curl_ver"; then
|
||||
AC_MSG_RESULT([yes, $CURL_VERSION])
|
||||
curl_tlsv2_ver=`echo 7.34.0 | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'`
|
||||
if test "$curl_tlsv2_ver" -le "$curl_ver"; then
|
||||
CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL_SSLVERSION_TLSv1_2"
|
||||
fi
|
||||
CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL"
|
||||
else
|
||||
AC_MSG_RESULT([no, $CURL_VERSION])
|
||||
AC_MSG_NOTICE([NOTE: curl library may be too old])
|
||||
fi
|
||||
|
||||
dnl # Check/warn if GnuTLS is used
|
||||
AC_MSG_CHECKING([if libcurl is linked with gnutls])
|
||||
curl_uses_gnutls=`echo ${CURL_LIBS} | grep gnutls | wc -l`
|
||||
if test "$curl_uses_gnutls" -ne 0; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_NOTICE([NOTE: curl linked with gnutls may be buggy, openssl recommended])
|
||||
CURL_USES_GNUTLS=yes
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
CURL_USES_GNUTLS=no
|
||||
fi
|
||||
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AC_SUBST(CURL_CONFIG)
|
||||
AC_SUBST(CURL_VERSION)
|
||||
AC_SUBST(CURL_CPPFLAGS)
|
||||
AC_SUBST(CURL_CFLAGS)
|
||||
AC_SUBST(CURL_LDFLAGS)
|
||||
AC_SUBST(CURL_LDADD)
|
||||
AC_SUBST(CURL_USES_GNUTLS)
|
||||
|
||||
if test "x${with_curl}" == "xno"; then
|
||||
CURL_DISABLED=yes
|
||||
else
|
||||
if test "x${with_curl}" != "x"; then
|
||||
CURL_MANDATORY=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "${CURL_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** curl library not found.])
|
||||
if test -z "${CURL_MANDATORY}"; then
|
||||
if test -z "${CURL_DISABLED}"; then
|
||||
CURL_FOUND=0
|
||||
else
|
||||
CURL_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([Curl was explicitly referenced but it was not found])
|
||||
CURL_FOUND=-1
|
||||
fi
|
||||
else
|
||||
CURL_FOUND=1
|
||||
AC_MSG_NOTICE([using curl v${CURL_VERSION}])
|
||||
CURL_DISPLAY="${CURL_LDADD}, ${CURL_CFLAGS}"
|
||||
fi
|
||||
|
||||
AC_SUBST(CURL_FOUND)
|
||||
AC_SUBST(CURL_DISPLAY)
|
||||
])
|
|
@ -1,186 +0,0 @@
|
|||
dnl Check for GEOIP Libraries
|
||||
dnl CHECK_GEOIP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
dnl Sets:
|
||||
dnl GEOIP_CFLAGS
|
||||
dnl GEOIP_LDADD
|
||||
dnl GEOIP_LDFLAGS
|
||||
dnl GEOIP_LIBS
|
||||
dnl GEOIP_VERSION
|
||||
|
||||
AC_DEFUN([PROG_GEOIP], [
|
||||
|
||||
# Possible names for the geoip library/package (pkg-config)
|
||||
GEOIP_POSSIBLE_LIB_NAMES="geoip2 geoip GeoIP"
|
||||
|
||||
# Possible extensions for the library
|
||||
GEOIP_POSSIBLE_EXTENSIONS="so la sl dll dylib"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
GEOIP_POSSIBLE_PATHS="/usr/local/libgeoip /usr/local/geoip /usr/local /opt/libgeoip /opt/geoip /opt /usr /opt/local/include /opt/local /usr/lib /usr/local/lib /usr/lib64 /usr"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
GEOIP_VERSION=""
|
||||
GEOIP_CFLAGS=""
|
||||
GEOIP_CPPFLAGS=""
|
||||
GEOIP_LDADD=""
|
||||
GEOIP_LDFLAGS=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
geoip,
|
||||
AS_HELP_STRING(
|
||||
[--with-geoip=PATH],
|
||||
[Path to GeoIP (including headers). Use 'no' to disable GeoIP support.]
|
||||
)
|
||||
)
|
||||
|
||||
# AS_HELP_STRING(
|
||||
# [--without-geoip],
|
||||
# [Complete dsiables GeoIP support]
|
||||
# )
|
||||
|
||||
|
||||
if test "x${with_geoip}" == "xno"; then
|
||||
AC_DEFINE(HAVE_GEOIP, 0, [Support for GeoIP was disabled by the utilization of --without-geoip or --with-geoip=no])
|
||||
AC_MSG_NOTICE([Support for GeoIP was disabled by the utilization of --without-geoip or --with-geoip=no])
|
||||
GEOIP_DISABLED=yes
|
||||
else
|
||||
if test "x${with_geoip}" == "xyes"; then
|
||||
GEOIP_MANDATORY=yes
|
||||
AC_MSG_NOTICE([GeoIP support was marked as mandatory by the utilization of --with-geoip=yes])
|
||||
fi
|
||||
# for x in ${GEOIP_POSSIBLE_LIB_NAMES}; do
|
||||
# CHECK_FOR_GEOIP_AT(${x})
|
||||
# if test -n "${GEOIP_VERSION}"; then
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
|
||||
# if test "x${with_geoip}" != "xyes" or test "x${with_geoip}" == "xyes"; then
|
||||
if test "x${with_geoip}" == "x" || test "x${with_geoip}" == "xyes"; then
|
||||
# Nothing about GeoIP was informed, using the pkg-config to figure things out.
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
GEOIP_PKG_NAME=""
|
||||
for x in ${GEOIP_POSSIBLE_LIB_NAMES}; do
|
||||
if ${PKG_CONFIG} --exists ${x}; then
|
||||
GEOIP_PKG_NAME="$x"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_MSG_NOTICE([Nothing about GeoIP was informed during the configure phase. Trying to detect it on the platform...])
|
||||
if test -n "${GEOIP_PKG_NAME}"; then
|
||||
# Package was found using the pkg-config scripts
|
||||
GEOIP_VERSION="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --modversion`"
|
||||
GEOIP_CFLAGS="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --cflags`"
|
||||
GEOIP_LDADD="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --libs-only-l`"
|
||||
GEOIP_LDFLAGS="`${PKG_CONFIG} ${GEOIP_PKG_NAME} --libs-only-L --libs-only-other`"
|
||||
GEOIP_DISPLAY="${GEOIP_LDADD}, ${GEOIP_CFLAGS}"
|
||||
else
|
||||
# If pkg-config did not find anything useful, go over file lookup.
|
||||
for x in ${GEOIP_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_GEOIP_AT(${x})
|
||||
if test -n "${GEOIP_VERSION}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "x${with_geoip}" != "x"; then
|
||||
# An specific path was informed, lets check.
|
||||
GEOIP_MANDATORY=yes
|
||||
CHECK_FOR_GEOIP_AT(${with_geoip})
|
||||
fi
|
||||
# fi
|
||||
fi
|
||||
|
||||
if test -z "${GEOIP_CFLAGS}"; then
|
||||
if test -z "${GEOIP_MANDATORY}"; then
|
||||
if test -z "${GEOIP_DISABLED}"; then
|
||||
AC_MSG_NOTICE([GeoIP library was not found])
|
||||
GEOIP_FOUND=0
|
||||
else
|
||||
GEOIP_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([GeoIP was explicit requested but it was not found])
|
||||
GEOIP_FOUND=-1
|
||||
fi
|
||||
else
|
||||
GEOIP_FOUND=1
|
||||
AC_MSG_NOTICE([using GeoIP v${GEOIP_VERSION}])
|
||||
GEOIP_CFLAGS="-DWITH_GEOIP ${GEOIP_CFLAGS}"
|
||||
AC_SUBST(GEOIP_VERSION)
|
||||
AC_SUBST(GEOIP_LDADD)
|
||||
AC_SUBST(GEOIP_LIBS)
|
||||
AC_SUBST(GEOIP_LDFLAGS)
|
||||
AC_SUBST(GEOIP_CFLAGS)
|
||||
AC_SUBST(GEOIP_DISPLAY)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
AC_SUBST(GEOIP_FOUND)
|
||||
|
||||
]) # AC_DEFUN [PROG_GEOIP]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_GEOIP_AT], [
|
||||
path=$1
|
||||
for y in ${GEOIP_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${GEOIP_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
geoip_lib_path="${path}/"
|
||||
geoip_lib_name="${z}"
|
||||
geoip_lib_file="${geoip_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
geoip_lib_path="${path}/"
|
||||
geoip_lib_name="${z}"
|
||||
geoip_lib_file="${geoip_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
geoip_lib_path="${path}/lib/"
|
||||
geoip_lib_name="${z}"
|
||||
geoip_lib_file="${geoip_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib64/lib${z}.${y}"; then
|
||||
geoip_lib_path="${path}/lib64/"
|
||||
geoip_lib_name="${z}"
|
||||
geoip_lib_file="${geoip_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
geoip_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
geoip_lib_name="${z}"
|
||||
geoip_lib_file="${geoip_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$geoip_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/GeoIPCity.h"; then
|
||||
geoip_inc_path="${path}/include"
|
||||
elif test -e "${path}/GeoIPCity.h"; then
|
||||
geoip_inc_path="${path}"
|
||||
fi
|
||||
|
||||
|
||||
if test -n "${geoip_inc_path}" -a -n "${geoip_lib_path}"; then
|
||||
|
||||
AC_MSG_NOTICE([GeoIP headers found at: ${geoip_inc_path}])
|
||||
AC_MSG_NOTICE([GeoIP library found at: ${geoip_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${geoip_lib_path}" -a -n "${geoip_inc_path}"; then
|
||||
# TODO: Compile a piece of code to check the version.
|
||||
GEOIP_CFLAGS="-I${geoip_inc_path}"
|
||||
GEOIP_LDADD="-l${geoip_lib_name}"
|
||||
GEOIP_LDFLAGS="-L${geoip_lib_path}"
|
||||
GEOIP_DISPLAY="${geoip_lib_file}, ${geoip_inc_path}"
|
||||
fi
|
||||
]) # AC_DEFUN [CHECK_FOR_GEOIP_AT]
|
|
@ -1,187 +0,0 @@
|
|||
dnl Check for MAXMIND Libraries
|
||||
dnl CHECK_MAXMIND(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
dnl Sets:
|
||||
dnl MAXMIND_CFLAGS
|
||||
dnl MAXMIND_LDADD
|
||||
dnl MAXMIND_LDFLAGS
|
||||
dnl MAXMIND_LIBS
|
||||
dnl MAXMIND_VERSION
|
||||
|
||||
AC_DEFUN([PROG_MAXMIND], [
|
||||
|
||||
# Possible names for the maxmind library/package (pkg-config)
|
||||
MAXMIND_POSSIBLE_LIB_NAMES="maxminddb maxmind"
|
||||
|
||||
# Possible extensions for the library
|
||||
MAXMIND_POSSIBLE_EXTENSIONS="so la sl dll dylib"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
MAXMIND_POSSIBLE_PATHS="/usr/local/libmaxmind /usr/local/maxmind /usr/local /opt/libmaxmind /opt/maxmind /opt /usr /opt/local/include /opt/local /usr/lib /usr/local/lib /usr/lib64 /usr /usr/include/x86_64-linux-gnu/"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
MAXMIND_VERSION=""
|
||||
MAXMIND_CFLAGS=""
|
||||
MAXMIND_CPPFLAGS=""
|
||||
MAXMIND_LDADD=""
|
||||
MAXMIND_LDFLAGS=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
maxmind,
|
||||
AS_HELP_STRING(
|
||||
[--with-maxmind=PATH],
|
||||
[Path to MaxMind (including headers). Use 'no' to disable MaxMind support.]
|
||||
)
|
||||
)
|
||||
|
||||
# AS_HELP_STRING(
|
||||
# [--without-maxmind],
|
||||
# [Complete dsiables MaxMind support]
|
||||
# )
|
||||
|
||||
|
||||
if test "x${with_maxmind}" == "xno"; then
|
||||
AC_DEFINE(HAVE_MAXMIND, 0, [Support for MaxMind was disabled by the utilization of --without-maxmind or --with-maxmind=no])
|
||||
AC_MSG_NOTICE([Support for MaxMind was disabled by the utilization of --without-maxmind or --with-maxmind=no])
|
||||
MAXMIND_DISABLED=yes
|
||||
else
|
||||
if test "x${with_maxmind}" == "xyes"; then
|
||||
MAXMIND_MANDATORY=yes
|
||||
AC_MSG_NOTICE([MaxMind support was marked as mandatory by the utilization of --with-maxmind=yes])
|
||||
fi
|
||||
# for x in ${MAXMIND_POSSIBLE_LIB_NAMES}; do
|
||||
# CHECK_FOR_MAXMIND_AT(${x})
|
||||
# if test -n "${MAXMIND_VERSION}"; then
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
|
||||
# if test "x${with_maxmind}" != "xyes" or test "x${with_maxmind}" == "xyes"; then
|
||||
if test "x${with_maxmind}" == "x" || test "x${with_maxmind}" == "xyes"; then
|
||||
# Nothing about MaxMind was informed, using the pkg-config to figure things out.
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
MAXMIND_PKG_NAME=""
|
||||
if ${PKG_CONFIG} --exists libmaxminddb; then
|
||||
MAXMIND_PKG_NAME="libmaxminddb"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
AC_MSG_NOTICE([Nothing about MaxMind was informed during the configure phase. Trying to detect it on the platform...])
|
||||
if test -n "${MAXMIND_PKG_NAME}"; then
|
||||
# Package was found using the pkg-config scripts
|
||||
MAXMIND_VERSION="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --modversion`"
|
||||
MAXMIND_CFLAGS="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --cflags`"
|
||||
MAXMIND_LDADD="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --libs-only-l`"
|
||||
MAXMIND_LDFLAGS="`${PKG_CONFIG} ${MAXMIND_PKG_NAME} --libs-only-L --libs-only-other`"
|
||||
MAXMIND_DISPLAY="${MAXMIND_LDADD}"
|
||||
else
|
||||
# If pkg-config did not find anything useful, go over file lookup.
|
||||
for x in ${MAXMIND_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_MAXMIND_AT(${x})
|
||||
if test -n "${MAXMIND_VERSION}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "x${with_maxmind}" != "x"; then
|
||||
# An specific path was informed, lets check.
|
||||
MAXMIND_MANDATORY=yes
|
||||
CHECK_FOR_MAXMIND_AT(${with_maxmind})
|
||||
fi
|
||||
# fi
|
||||
fi
|
||||
|
||||
if test -z "${MAXMIND_DISPLAY}"; then
|
||||
if test -z "${MAXMIND_MANDATORY}"; then
|
||||
if test -z "${MAXMIND_DISABLED}"; then
|
||||
AC_MSG_NOTICE([MaxMind library was not found])
|
||||
MAXMIND_FOUND=0
|
||||
else
|
||||
MAXMIND_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([MaxMind was explicit requested but it was not found])
|
||||
MAXMIND_FOUND=-1
|
||||
fi
|
||||
else
|
||||
MAXMIND_FOUND=1
|
||||
AC_MSG_NOTICE([using MaxMind v${MAXMIND_VERSION}])
|
||||
MAXMIND_CFLAGS="-DWITH_MAXMIND ${MAXMIND_CFLAGS}"
|
||||
if ! test "x$MAXMIND_CFLAGS" = "x"; then
|
||||
MAXMIND_DISPLAY="${MAXMIND_DISPLAY}, ${MAXMIND_CFLAGS}"
|
||||
fi
|
||||
AC_SUBST(MAXMIND_VERSION)
|
||||
AC_SUBST(MAXMIND_LDADD)
|
||||
AC_SUBST(MAXMIND_LIBS)
|
||||
AC_SUBST(MAXMIND_LDFLAGS)
|
||||
AC_SUBST(MAXMIND_CFLAGS)
|
||||
AC_SUBST(MAXMIND_DISPLAY)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
AC_SUBST(MAXMIND_FOUND)
|
||||
|
||||
]) # AC_DEFUN [PROG_MAXMIND]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_MAXMIND_AT], [
|
||||
path=$1
|
||||
for y in ${MAXMIND_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${MAXMIND_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
maxmind_lib_path="${path}/"
|
||||
maxmind_lib_name="${z}"
|
||||
maxmind_lib_file="${maxmind_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
maxmind_lib_path="${path}/"
|
||||
maxmind_lib_name="${z}"
|
||||
maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
maxmind_lib_path="${path}/lib/"
|
||||
maxmind_lib_name="${z}"
|
||||
maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib64/lib${z}.${y}"; then
|
||||
maxmind_lib_path="${path}/lib64/"
|
||||
maxmind_lib_name="${z}"
|
||||
maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
maxmind_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
maxmind_lib_name="${z}"
|
||||
maxmind_lib_file="${maxmind_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$maxmind_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/maxminddb.h"; then
|
||||
maxmind_inc_path="${path}/include"
|
||||
elif test -e "${path}/maxminddb.h"; then
|
||||
maxmind_inc_path="${path}"
|
||||
fi
|
||||
|
||||
|
||||
if test -n "${maxmind_inc_path}" -a -n "${maxmind_lib_path}"; then
|
||||
|
||||
AC_MSG_NOTICE([MaxMind headers found at: ${maxmind_inc_path}])
|
||||
AC_MSG_NOTICE([MaxMind library found at: ${maxmind_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${maxmind_lib_path}" -a -n "${maxmind_inc_path}"; then
|
||||
# TODO: Compile a piece of code to check the version.
|
||||
MAXMIND_CFLAGS="-I${maxmind_inc_path}"
|
||||
MAXMIND_LDADD="-l${maxmind_lib_name}"
|
||||
MAXMIND_LDFLAGS="-L${maxmind_lib_path}"
|
||||
MAXMIND_DISPLAY="${maxmind_lib_file}, ${maxmind_inc_path}"
|
||||
fi
|
||||
]) # AC_DEFUN [CHECK_FOR_MAXMIND_AT]
|
|
@ -1,135 +0,0 @@
|
|||
dnl Check for LIBXML2 Libraries
|
||||
dnl CHECK_LIBXML2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
dnl Sets:
|
||||
dnl LIBXML2_CFLAGS
|
||||
dnl LIBXML2_LIBS
|
||||
|
||||
AC_DEFUN([CHECK_XML2CONFIG], [
|
||||
|
||||
AC_MSG_CHECKING([for libxml2 config script])
|
||||
|
||||
for x in ${test_paths}; do
|
||||
dnl # Determine if the script was specified and use it directly
|
||||
if test ! -d "$x" -a -e "$x"; then
|
||||
LIBXML2_CONFIG=$x
|
||||
libxml2_path="no"
|
||||
break
|
||||
fi
|
||||
|
||||
dnl # Try known config script names/locations
|
||||
for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do
|
||||
if test -e "${x}/bin/${LIBXML2_CONFIG}"; then
|
||||
libxml2_path="${x}/bin"
|
||||
break
|
||||
elif test -e "${x}/${LIBXML2_CONFIG}"; then
|
||||
libxml2_path="${x}"
|
||||
break
|
||||
else
|
||||
libxml2_path=""
|
||||
fi
|
||||
done
|
||||
if test -n "$libxml2_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -n "${libxml2_path}"; then
|
||||
if test "${libxml2_path}" != "no"; then
|
||||
LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}"
|
||||
fi
|
||||
AC_MSG_RESULT([${LIBXML2_CONFIG}])
|
||||
LIBXML2_VERSION=`${LIBXML2_CONFIG} --version | sed 's/^[[^0-9]][[^[:space:]]][[^[:space:]]]*[[[:space:]]]*//'`
|
||||
if test ! -z "${LIBXML2_VERSION}"; then AC_MSG_NOTICE(xml VERSION: $LIBXML2_VERSION); fi
|
||||
LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags` -DWITH_LIBXML2"
|
||||
if test ! -z "${LIBXML2_CFLAGS}"; then AC_MSG_NOTICE(xml CFLAGS: $LIBXML2_CFLAGS); fi
|
||||
LIBXML2_LDADD="`${LIBXML2_CONFIG} --libs`"
|
||||
if test ! -z "${LIBXML2_LDADD}"; then AC_MSG_NOTICE(xml LDADD: $LIBXML2_LDADD); fi
|
||||
|
||||
AC_MSG_CHECKING([if libxml2 is at least v${LIBXML2_MIN_VERSION}])
|
||||
libxml2_min_ver=`echo ${LIBXML2_MIN_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'`
|
||||
libxml2_ver=`echo ${LIBXML2_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'`
|
||||
if test "$libxml2_ver" -ge "$libxml2_min_ver"; then
|
||||
AC_MSG_RESULT([yes, $LIBXML2_VERSION])
|
||||
else
|
||||
AC_MSG_RESULT([no, $LIBXML2_VERSION])
|
||||
AC_MSG_ERROR([NOTE: libxml2 library must be at least ${LIBXML2_MIN_VERSION}])
|
||||
fi
|
||||
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([CHECK_LIBXML2], [
|
||||
|
||||
AC_ARG_WITH(
|
||||
libxml,
|
||||
[AS_HELP_STRING([--with-libxml=PATH],[Path to libxml2 prefix or config script])],
|
||||
[test_paths="${with_libxml}"],
|
||||
[test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr"])
|
||||
|
||||
LIBXML2_MIN_VERSION="2.6.29"
|
||||
LIBXML2_PKG_NAME="libxml-2.0"
|
||||
LIBXML2_CONFIG=""
|
||||
LIBXML2_VERSION=""
|
||||
LIBXML2_CFLAGS=""
|
||||
LIBXML2_CPPFLAGS=""
|
||||
LIBXML2_LDADD=""
|
||||
LIBXML2_LDFLAGS=""
|
||||
|
||||
if test "x${with_libxml}" != "xno"; then
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
AC_MSG_CHECKING([for libxml2 >= ${LIBXML2_MIN_VERSION} via pkg-config])
|
||||
if `${PKG_CONFIG} --exists "${LIBXML2_PKG_NAME} >= ${LIBXML2_MIN_VERSION}"`; then
|
||||
LIBXML2_VERSION="`${PKG_CONFIG} --modversion ${LIBXML2_PKG_NAME}`"
|
||||
LIBXML2_CFLAGS="`${PKG_CONFIG} --cflags ${LIBXML2_PKG_NAME}` -DWITH_LIBXML2"
|
||||
LIBXML2_LDADD="`${PKG_CONFIG} --libs-only-l ${LIBXML2_PKG_NAME}`"
|
||||
LIBXML2_LDFLAGS="`${PKG_CONFIG} --libs-only-L --libs-only-other ${LIBXML2_PKG_NAME}`"
|
||||
AC_MSG_RESULT([found version ${LIBXML2_VERSION}])
|
||||
else
|
||||
AC_MSG_RESULT([not found])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "${LIBXML2_VERSION}"; then
|
||||
CHECK_XML2CONFIG
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBXML2_CONFIG)
|
||||
AC_SUBST(LIBXML2_VERSION)
|
||||
AC_SUBST(LIBXML2_CFLAGS)
|
||||
AC_SUBST(LIBXML2_CPPFLAGS)
|
||||
AC_SUBST(LIBXML2_LDADD)
|
||||
AC_SUBST(LIBXML2_LDFLAGS)
|
||||
|
||||
|
||||
if test "x${with_libxml}" == "xno"; then
|
||||
LIBXML2_DISABLED=yes
|
||||
else
|
||||
if test "x${with_libxml}" != "x"; then
|
||||
LIBXML2_MANDATORY=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "${LIBXML2_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** libxml2 library not found.])
|
||||
if test -z "${LIBXML2_MANDATORY}"; then
|
||||
if test -z "${LIBXML2_DISABLED}"; then
|
||||
LIBXML2_FOUND=0
|
||||
else
|
||||
LIBXML2_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([Libxml2 was explicitly referenced but it was not found])
|
||||
LIBXML2_FOUND=-1
|
||||
fi
|
||||
else
|
||||
LIBXML2_FOUND=1
|
||||
AC_MSG_NOTICE([using libxml2 v${LIBXML2_VERSION}])
|
||||
LIBXML2_DISPLAY="${LIBXML2_LDADD}, ${LIBXML2_CFLAGS}"
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBXML2_FOUND)
|
||||
AC_SUBST(LIBXML2_DISPLAY)
|
||||
])
|
|
@ -1,180 +0,0 @@
|
|||
dnl Check for LMDB Libraries
|
||||
dnl CHECK_LMDB(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([PROG_LMDB], [
|
||||
|
||||
# Possible names for the lmdb library/package (pkg-config)
|
||||
LMDB_POSSIBLE_LIB_NAMES="lmdb"
|
||||
|
||||
# Possible extensions for the library
|
||||
LMDB_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
LMDB_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/liblmdb /usr/local/lmdb /usr/local /opt/liblmdb /opt/lmdb /opt /usr /usr/lib64 /opt/local"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
LMDB_VERSION=""
|
||||
LMDB_CFLAGS=""
|
||||
LMDB_CPPFLAGS=""
|
||||
LMDB_LDADD=""
|
||||
LMDB_LDFLAGS=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
lmdb,
|
||||
[AS_HELP_STRING([--with-lmdb=PATH],[Path to lmdb prefix or config script])]
|
||||
)
|
||||
|
||||
if test "x${with_lmdb}" == "xno"; then
|
||||
AC_DEFINE(HAVE_LMDB, 0, [Support for LMDB was disabled by the utilization of --without-lmdb or --with-lmdb=no])
|
||||
AC_MSG_NOTICE([Support for LMDB was disabled by the utilization of --without-lmdb or --with-lmdb=no])
|
||||
LMDB_DISABLED=yes
|
||||
else
|
||||
if test "x${with_lmdb}" == "xyes"; then
|
||||
LMDB_MANDATORY=yes
|
||||
AC_MSG_NOTICE([LMDB support was marked as mandatory by the utilization of --with-lmdb=yes])
|
||||
fi
|
||||
# for x in ${LMDB_POSSIBLE_LIB_NAMES}; do
|
||||
# CHECK_FOR_LMDB_AT(${x})
|
||||
# if test -n "${LMDB_VERSION}"; then
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
|
||||
# if test "x${with_lmdb}" != "xyes" or test "x${with_lmdb}" == "xyes"; then
|
||||
if test "x${with_lmdb}" == "x" || test "x${with_lmdb}" == "xyes"; then
|
||||
# Nothing about LMDB was informed, using the pkg-config to figure things out.
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
LMDB_PKG_NAME=""
|
||||
for x in ${LMDB_POSSIBLE_LIB_NAMES}; do
|
||||
if ${PKG_CONFIG} --exists ${x}; then
|
||||
LMDB_PKG_NAME="$x"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_MSG_NOTICE([Nothing about LMDB was informed during the configure phase. Trying to detect it on the platform...])
|
||||
if test -n "${LMDB_PKG_NAME}"; then
|
||||
# Package was found using the pkg-config scripts
|
||||
LMDB_VERSION="`${PKG_CONFIG} ${LMDB_PKG_NAME} --modversion`"
|
||||
LMDB_CFLAGS="`${PKG_CONFIG} ${LMDB_PKG_NAME} --cflags`"
|
||||
LMDB_LDADD="`${PKG_CONFIG} ${LMDB_PKG_NAME} --libs-only-l`"
|
||||
LMDB_LDFLAGS="`${PKG_CONFIG} ${LMDB_PKG_NAME} --libs-only-L --libs-only-other`"
|
||||
LMDB_DISPLAY="${LMDB_LDADD}, ${LMDB_CFLAGS}"
|
||||
else
|
||||
# If pkg-config did not find anything useful, go over file lookup.
|
||||
for x in ${LMDB_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_LMDB_AT(${x})
|
||||
if test -n "${LMDB_VERSION}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "x${with_lmdb}" != "x"; then
|
||||
# An specific path was informed, lets check.
|
||||
LMDB_MANDATORY=yes
|
||||
CHECK_FOR_LMDB_AT(${with_lmdb})
|
||||
fi
|
||||
# fi
|
||||
fi
|
||||
|
||||
if test -z "${LMDB_LDADD}"; then
|
||||
if test -z "${LMDB_MANDATORY}"; then
|
||||
if test -z "${LMDB_DISABLED}"; then
|
||||
AC_MSG_NOTICE([LMDB library was not found])
|
||||
LMDB_FOUND=0
|
||||
else
|
||||
LMDB_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([LMDB was explicitly referenced but it was not found])
|
||||
LMDB_FOUND=-1
|
||||
fi
|
||||
else
|
||||
if test -z "${LMDB_MANDATORY}"; then
|
||||
LMDB_FOUND=2
|
||||
AC_MSG_NOTICE([LMDB is disabled by default.])
|
||||
else
|
||||
LMDB_FOUND=1
|
||||
AC_MSG_NOTICE([using LMDB v${LMDB_VERSION}])
|
||||
LMDB_CFLAGS="-DWITH_LMDB ${LMDB_CFLAGS}"
|
||||
LMDB_DISPLAY="${LMDB_LDADD}, ${LMDB_CFLAGS}"
|
||||
AC_SUBST(LMDB_VERSION)
|
||||
AC_SUBST(LMDB_LDADD)
|
||||
AC_SUBST(LMDB_LIBS)
|
||||
AC_SUBST(LMDB_LDFLAGS)
|
||||
AC_SUBST(LMDB_CFLAGS)
|
||||
AC_SUBST(LMDB_DISPLAY)
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_SUBST(LMDB_FOUND)
|
||||
|
||||
]) # AC_DEFUN [PROG_LMDB]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_LMDB_AT], [
|
||||
path=$1
|
||||
echo "*** LOOKING AT PATH: " ${path}
|
||||
for y in ${LMDB_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${LMDB_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
lmdb_lib_path="${path}/"
|
||||
lmdb_lib_name="${z}"
|
||||
lmdb_lib_file="${lmdb_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
lmdb_lib_path="${path}/"
|
||||
lmdb_lib_name="${z}"
|
||||
lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
lmdb_lib_path="${path}/lib/"
|
||||
lmdb_lib_name="${z}"
|
||||
lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
lmdb_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
lmdb_lib_name="${z}"
|
||||
lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then
|
||||
lmdb_lib_path="${path}/lib/i386-linux-gnu/"
|
||||
lmdb_lib_name="${z}"
|
||||
lmdb_lib_file="${lmdb_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$lmdb_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/lmdb.h"; then
|
||||
lmdb_inc_path="${path}/include"
|
||||
elif test -e "${path}/lmdb.h"; then
|
||||
lmdb_inc_path="${path}"
|
||||
elif test -e "${path}/include/lmdb/lmdb.h"; then
|
||||
lmdb_inc_path="${path}/include"
|
||||
fi
|
||||
|
||||
if test -n "${lmdb_lib_path}"; then
|
||||
AC_MSG_NOTICE([LMDB library found at: ${lmdb_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${lmdb_inc_path}"; then
|
||||
AC_MSG_NOTICE([LMDB headers found at: ${lmdb_inc_path}])
|
||||
fi
|
||||
|
||||
if test -n "${lmdb_lib_path}" -a -n "${lmdb_inc_path}"; then
|
||||
# TODO: Compile a piece of code to check the version.
|
||||
LMDB_CFLAGS="-I${lmdb_inc_path}"
|
||||
LMDB_LDADD="-l${lmdb_lib_name}"
|
||||
LMDB_LDFLAGS="-L${lmdb_lib_path}"
|
||||
LMDB_DISPLAY="${lmdb_lib_file}, ${lmdb_inc_path}"
|
||||
fi
|
||||
]) # AC_DEFUN [CHECK_FOR_LMDB_AT]
|
|
@ -1,248 +0,0 @@
|
|||
dnl Check for LUA Libraries
|
||||
dnl CHECK_LUA(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_LUA],
|
||||
[dnl
|
||||
|
||||
# Possible names for the lua library/package (pkg-config)
|
||||
LUA_POSSIBLE_LIB_NAMES="lua54 lua5.4 lua-5.4 lua53 lua5.3 lua-5.3 lua52 lua5.2 lua-5.2 lua51 lua5.1 lua-5.1 lua"
|
||||
|
||||
# Possible extensions for the library
|
||||
LUA_POSSIBLE_EXTENSIONS="so la sl dll dylib"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
LUA_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/lib64 /usr/local/lua /usr/local/liblua /usr/local /opt /usr /usr/lib64 /opt/local /usr/lib/lua5.3/liblua /usr/lib/lua5.2/liblua"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
LUA_CFLAGS=""
|
||||
LUA_LDFLAGS=""
|
||||
LUA_LDADD=""
|
||||
LUA_DISPLAY=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
lua,
|
||||
[AS_HELP_STRING([--with-lua=PATH],[Path to lua prefix])]
|
||||
)
|
||||
|
||||
|
||||
if test "x${with_lua}" == "xno"; then
|
||||
AC_DEFINE(HAVE_LUA, 0, [Support for LUA was disabled by the utilization of --without-lua or --with-lua=no])
|
||||
AC_MSG_NOTICE([Support for LUA was disabled by the utilization of --without-lua or --with-lua=no])
|
||||
LUA_DISABLED=yes
|
||||
else
|
||||
if test "x${with_lua}" == "xyes"; then
|
||||
LUA_MANDATORY=yes
|
||||
AC_MSG_NOTICE([LUA support was marked as mandatory by the utilization of --with-lua=yes])
|
||||
else
|
||||
LUA_MANDATORY=no
|
||||
fi
|
||||
for x in ${LUA_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_LUA_AT(${x})
|
||||
if test -n "${LUA_CFLAGS}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "${LUA_CFLAGS}"; then
|
||||
#Trying to figure out the version using pkg-config...
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
LUA_PKG_NAME=""
|
||||
for x in ${LUA_POSSIBLE_LIB_NAMES}; do
|
||||
if ${PKG_CONFIG} --exists ${x}; then
|
||||
LUA_PKG_NAME="$x"
|
||||
LUA_PKG_VERSION="`${PKG_CONFIG} ${LUA_PKG_NAME} --modversion`"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test -n "${LUA_PKG_NAME}"; then
|
||||
# Package was found using the pkg-config scripts
|
||||
LUA_PKG_VERSION="`${PKG_CONFIG} ${LUA_PKG_NAME} --modversion`"
|
||||
LUA_CFLAGS="`${PKG_CONFIG} ${LUA_PKG_NAME} --cflags`"
|
||||
LUA_LDADD="`${PKG_CONFIG} ${LUA_PKG_NAME} --libs-only-l`"
|
||||
LUA_LDFLAGS="`${PKG_CONFIG} ${LUA_PKG_NAME} --libs-only-L --libs-only-other`"
|
||||
LUA_DISPLAY="${LUA_LDADD}, ${LUA_CFLAGS}"
|
||||
case $LUA_PKG_VERSION in
|
||||
(5.1*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;;
|
||||
(5.2*) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ; lua_5_2=1 ;;
|
||||
(5.3*) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ; lua_5_3=1 ;;
|
||||
(5.4*) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ; lua_5_4=1 ;;
|
||||
(2.0*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;;
|
||||
(2.1*) LUA_CFLAGS="-DWITH_LUA_5_1 -DWITH_LUA_JIT_2_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;;
|
||||
esac
|
||||
AC_MSG_NOTICE([LUA pkg-config version: ${LUA_PKG_VERSION}])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if test -z "${LUA_CFLAGS}"; then
|
||||
if test -z "${LUA_MANDATORY}" || test "x${LUA_MANDATORY}" == "xno"; then
|
||||
if test -z "${LUA_DISABLED}"; then
|
||||
AC_MSG_NOTICE([LUA library was not found])
|
||||
LUA_FOUND=0
|
||||
else
|
||||
LUA_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([LUA was explicitly referenced but it was not found])
|
||||
LUA_FOUND=-1
|
||||
fi
|
||||
else
|
||||
if test -z "${LUA_MANDATORY}" || test "x${LUA_MANDATORY}" == "xno"; then
|
||||
LUA_FOUND=1
|
||||
AC_MSG_NOTICE([using LUA ${LUA_LDADD}])
|
||||
LUA_CFLAGS="-DWITH_LUA ${LUA_CFLAGS}"
|
||||
LUA_DISPLAY="${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}"
|
||||
AC_SUBST(LUA_LDFLAGS)
|
||||
AC_SUBST(LUA_LDADD)
|
||||
AC_SUBST(LUA_CFLAGS)
|
||||
AC_SUBST(LUA_DISPLAY)
|
||||
else
|
||||
LUA_FOUND=1
|
||||
AC_MSG_NOTICE([using LUA ${LUA_LDADD}])
|
||||
LUA_CFLAGS="-DWITH_LUA ${LUA_CFLAGS}"
|
||||
LUA_DISPLAY="${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}"
|
||||
AC_SUBST(LUA_LDFLAGS)
|
||||
AC_SUBST(LUA_LDADD)
|
||||
AC_SUBST(LUA_CFLAGS)
|
||||
AC_SUBST(LUA_DISPLAY)
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LUA_FOUND)
|
||||
|
||||
]) # AC_DEFUN [CHECK_LUA]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_LUA_AT], [
|
||||
path=$1
|
||||
echo "*** LOOKING AT PATH: " ${path}
|
||||
for y in ${LUA_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${LUA_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
lua_lib_path="${path}/"
|
||||
lua_lib_name="${z}"
|
||||
lua_lib_file="${lua_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
lua_lib_path="${path}/"
|
||||
lua_lib_name="${z}"
|
||||
lua_lib_file="${lua_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
lua_lib_path="${path}/lib/"
|
||||
lua_lib_name="${z}"
|
||||
lua_lib_file="${lua_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
lua_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
lua_lib_name="${z}"
|
||||
lua_lib_file="${lua_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then
|
||||
lua_lib_path="${path}/lib/i386-linux-gnu/"
|
||||
lua_lib_name="${z}"
|
||||
lua_lib_file="${lua_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$lua_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/lua.h"; then
|
||||
lua_inc_path="${path}/include"
|
||||
elif test -e "${path}/lua.h"; then
|
||||
lua_inc_path="${path}"
|
||||
elif test -e "${path}/include/lua/lua.h"; then
|
||||
lua_inc_path="${path}/include/lua"
|
||||
elif test -e "${path}/include/lua5.4/lua.h"; then
|
||||
lua_inc_path="${path}/include/lua5.4"
|
||||
LUA_VERSION=504
|
||||
elif test -e "${path}/include/lua5.3/lua.h"; then
|
||||
lua_inc_path="${path}/include/lua5.3"
|
||||
LUA_VERSION=503
|
||||
elif test -e "${path}/include/lua5.2/lua.h"; then
|
||||
lua_inc_path="${path}/include/lua5.2"
|
||||
LUA_VERSION=502
|
||||
elif test -e "${path}/include/lua5.1/lua.h"; then
|
||||
lua_inc_path="${path}/include/lua5.1"
|
||||
LUA_VERSION=501
|
||||
elif test -e "${path}/include/luajit-2.0/lua.h"; then
|
||||
lua_inc_path="${path}/include/luajit-2.0"
|
||||
LUA_VERSION=501
|
||||
fi
|
||||
|
||||
if test -n "${lua_lib_path}"; then
|
||||
AC_MSG_NOTICE([LUA library found at: ${lua_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${lua_inc_path}"; then
|
||||
AC_MSG_NOTICE([LUA headers found at: ${lua_inc_path}])
|
||||
fi
|
||||
if test -n "${lua_lib_path}" -a -n "${lua_inc_path}"; then
|
||||
LUA_CFLAGS="-I${lua_inc_path}"
|
||||
LUA_LDADD="-l${lua_lib_name}"
|
||||
LUA_LDFLAGS="-L${lua_lib_path}"
|
||||
LUA_DISPLAY="${lua_lib_file}, ${lua_inc_path}"
|
||||
|
||||
# Double checking version from lua.h...
|
||||
AC_TRY_COMPILE([ #include <lua.h>> ],
|
||||
[ #if (LUA_VERSION_NUM < 502)
|
||||
return 0;
|
||||
#else
|
||||
#error Lua 5.1 not detected
|
||||
#endif ],
|
||||
[ LUA_VERSION=501 ], [ lua_5_1=0 ]
|
||||
)
|
||||
|
||||
AC_TRY_COMPILE([ #include <lua.h> ],
|
||||
[ #if (LUA_VERSION_NUM == 502)
|
||||
return 0;
|
||||
#else
|
||||
#error Lua 5.2 not detected
|
||||
#endif ],
|
||||
[ LUA_VERSION=502 ], [ lua_5_2=0 ]
|
||||
)
|
||||
AC_TRY_COMPILE([ #include <lua.h> ],
|
||||
[ #if (LUA_VERSION_NUM == 504)
|
||||
return 0;
|
||||
#else
|
||||
#error Lua 5.4 not detected
|
||||
#endif ],
|
||||
[ LUA_VERSION=504 ], [ lua_5_4=0 ]
|
||||
)
|
||||
|
||||
if test -z "${LUA_VERSION}" ; then
|
||||
# As a last resort, try to find LUA version from $lua_inc_path
|
||||
while read -r line
|
||||
do
|
||||
case "$line" in
|
||||
(\#define\ LUA_VERSION_NUM*501*) LUA_VERSION=501 ;;
|
||||
(\#define\ LUA_VERSION_NUM*502*) LUA_VERSION=502 ;;
|
||||
(\#define\ LUA_VERSION_NUM*503*) LUA_VERSION=503 ;;
|
||||
(\#define\ LUA_VERSION_NUM*504*) LUA_VERSION=504
|
||||
esac
|
||||
done <"${lua_inc_path}/lua.h"
|
||||
AC_MSG_NOTICE([LUA_VERSION is ${LUA_VERSION} found at: ${lua_inc_path}])
|
||||
else
|
||||
AC_MSG_NOTICE([LUA version from includes: ${LUA_VERSION}])
|
||||
fi
|
||||
|
||||
case $LUA_VERSION in
|
||||
(501) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ; lua_5_1=1 ;;
|
||||
(502) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ; lua_5_2=1 ;;
|
||||
(503) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ; lua_5_3=1 ;;
|
||||
(504) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ; lua_5_4=1 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
]) # AC_DEFUN [CHECK_FOR_LUA_AT]
|
||||
|
||||
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
dnl Check for PCRE Libraries
|
||||
dnl CHECK_PCRE(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
dnl Sets:
|
||||
dnl PCRE_CFLAGS
|
||||
dnl PCRE_LIBS
|
||||
|
||||
PCRE_CONFIG=""
|
||||
PCRE_VERSION=""
|
||||
PCRE_CPPFLAGS=""
|
||||
PCRE_CFLAGS=""
|
||||
PCRE_LDFLAGS=""
|
||||
PCRE_LDADD=""
|
||||
PCRE_LD_PATH=""
|
||||
|
||||
AC_DEFUN([CHECK_PCRE],
|
||||
[dnl
|
||||
|
||||
AC_ARG_WITH(
|
||||
pcre,
|
||||
[AS_HELP_STRING([--with-pcre=PATH],[Path to pcre prefix or config script])],
|
||||
[test_paths="${with_pcre}"],
|
||||
[test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr /opt/local"])
|
||||
|
||||
if test "x${with_pcre2}" != "x" && test "x${with_pcre2}" != "xno"; then
|
||||
AC_MSG_NOTICE([pcre2 specified; omitting check for pcre])
|
||||
else
|
||||
|
||||
AC_MSG_CHECKING([for libpcre config script])
|
||||
|
||||
for x in ${test_paths}; do
|
||||
dnl # Determine if the script was specified and use it directly
|
||||
if test ! -d "$x" -a -e "$x"; then
|
||||
PCRE_CONFIG=$x
|
||||
pcre_path="no"
|
||||
break
|
||||
fi
|
||||
|
||||
dnl # Try known config script names/locations
|
||||
for PCRE_CONFIG in pcre-config; do
|
||||
if test -e "${x}/bin/${PCRE_CONFIG}"; then
|
||||
pcre_path="${x}/bin"
|
||||
break
|
||||
elif test -e "${x}/${PCRE_CONFIG}"; then
|
||||
pcre_path="${x}"
|
||||
break
|
||||
else
|
||||
pcre_path=""
|
||||
fi
|
||||
done
|
||||
if test -n "$pcre_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -n "${pcre_path}"; then
|
||||
if test "${pcre_path}" != "no"; then
|
||||
PCRE_CONFIG="${pcre_path}/${PCRE_CONFIG}"
|
||||
fi
|
||||
AC_MSG_RESULT([${PCRE_CONFIG}])
|
||||
PCRE_VERSION="`${PCRE_CONFIG} --version`"
|
||||
if test ! -z "${PCRE_VERSION}"; then AC_MSG_NOTICE(pcre VERSION: $PCRE_VERSION); fi
|
||||
PCRE_CFLAGS="`${PCRE_CONFIG} --cflags`"
|
||||
if test ! -z "${PCRE_CFLAGS}"; then AC_MSG_NOTICE(pcre CFLAGS: $PCRE_CFLAGS); fi
|
||||
PCRE_LDADD="`${PCRE_CONFIG} --libs`"
|
||||
if test ! -z "${PCRE_LDADD}"; then AC_MSG_NOTICE(pcre LDADD: $PCRE_LDADD); fi
|
||||
PCRE_LD_PATH="/`${PCRE_CONFIG} --libs | cut -d'/' -f2,3,4,5,6 | cut -d ' ' -f1`"
|
||||
if test ! -z "${PCRE_LD_PATH}"; then AC_MSG_NOTICE(pcre PCRE_LD_PATH: $PCRE_LD_PATH); fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
if test -n "${PCRE_VERSION}"; then
|
||||
AC_MSG_CHECKING(for PCRE JIT)
|
||||
save_CFLAGS=$CFLAGS
|
||||
save_LDFLAGS=$LDFLAGS
|
||||
save_LIBS=$LIBS
|
||||
CFLAGS="${PCRE_CFLAGS} ${CFLAGS}"
|
||||
LDFLAGS="${PCRE_LDADD} ${LDFLAGS}"
|
||||
LIBS="${PCRE_LDADD} ${LIBS}"
|
||||
AC_TRY_LINK([ #include <pcre.h> ],
|
||||
[ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ],
|
||||
[ pcre_jit_available=yes ], [:]
|
||||
)
|
||||
|
||||
if test "x$pcre_jit_available" = "xyes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
PCRE_CFLAGS="${PCRE_CFLAGS} -DPCRE_HAVE_JIT"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
CFLAGS=$save_CFLAGS
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
LIBS=$save_LIBS
|
||||
fi
|
||||
|
||||
AC_SUBST(PCRE_CONFIG)
|
||||
AC_SUBST(PCRE_VERSION)
|
||||
AC_SUBST(PCRE_CPPFLAGS)
|
||||
AC_SUBST(PCRE_CFLAGS)
|
||||
AC_SUBST(PCRE_LDFLAGS)
|
||||
AC_SUBST(PCRE_LDADD)
|
||||
AC_SUBST(PCRE_LD_PATH)
|
||||
|
||||
if test -z "${PCRE_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** pcre library not found.])
|
||||
ifelse([$2], , AC_MSG_ERROR([pcre library is required]), $2)
|
||||
else
|
||||
AC_MSG_NOTICE([using pcre v${PCRE_VERSION}])
|
||||
ifelse([$1], , , $1)
|
||||
PCRE_LDADD="${PCRE_LDADD} -lpcre"
|
||||
fi
|
||||
fi
|
||||
])
|
|
@ -1,180 +0,0 @@
|
|||
dnl Check for PCRE2 Libraries
|
||||
dnl CHECK_PCRE2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([PROG_PCRE2], [
|
||||
|
||||
# Possible names for the pcre2 library/package (pkg-config)
|
||||
PCRE2_POSSIBLE_LIB_NAMES="pcre2 pcre2-8"
|
||||
|
||||
# Possible extensions for the library
|
||||
PCRE2_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
PCRE2_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/libpcre2-8 /usr/local/pcre2 /usr/local /opt/libpcre2-8 /opt/pcre2 /opt /usr /usr/lib64 /opt/local"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
PCRE2_VERSION=""
|
||||
PCRE2_CFLAGS=""
|
||||
PCRE2_CPPFLAGS=""
|
||||
PCRE2_LDADD=""
|
||||
PCRE2_LDFLAGS=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
pcre2,
|
||||
[AS_HELP_STRING([--with-pcre2=PATH],[Path to pcre2 prefix or config script])]
|
||||
)
|
||||
|
||||
if test "x${with_pcre2}" == "xno"; then
|
||||
AC_DEFINE(HAVE_PCRE2, 0, [Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no])
|
||||
AC_MSG_NOTICE([Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no])
|
||||
PCRE2_DISABLED=yes
|
||||
else
|
||||
if test "x${with_pcre2}" == "xyes"; then
|
||||
PCRE2_MANDATORY=yes
|
||||
AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes])
|
||||
fi
|
||||
# for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do
|
||||
# CHECK_FOR_PCRE2_AT(${x})
|
||||
# if test -n "${PCRE2_VERSION}"; then
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
|
||||
# if test "x${with_pcre2}" != "xyes" or test "x${with_pcre2}" == "xyes"; then
|
||||
if test "x${with_pcre2}" == "x" || test "x${with_pcre2}" == "xyes"; then
|
||||
# Nothing about PCRE2 was informed, using the pkg-config to figure things out.
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
PCRE2_PKG_NAME=""
|
||||
for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do
|
||||
if ${PKG_CONFIG} --exists ${x}; then
|
||||
PCRE2_PKG_NAME="$x"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_MSG_NOTICE([Nothing about PCRE2 was informed during the configure phase. Trying to detect it on the platform...])
|
||||
if test -n "${PCRE2_PKG_NAME}"; then
|
||||
# Package was found using the pkg-config scripts
|
||||
PCRE2_VERSION="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --modversion`"
|
||||
PCRE2_CFLAGS="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --cflags`"
|
||||
PCRE2_LDADD="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --libs-only-l`"
|
||||
PCRE2_LDFLAGS="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --libs-only-L --libs-only-other`"
|
||||
PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}"
|
||||
else
|
||||
# If pkg-config did not find anything useful, go over file lookup.
|
||||
for x in ${PCRE2_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_PCRE2_AT(${x})
|
||||
if test -n "${PCRE2_VERSION}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "x${with_pcre2}" != "x"; then
|
||||
# An specific path was informed, lets check.
|
||||
PCRE2_MANDATORY=yes
|
||||
CHECK_FOR_PCRE2_AT(${with_pcre2})
|
||||
fi
|
||||
# fi
|
||||
fi
|
||||
|
||||
if test -z "${PCRE2_LDADD}"; then
|
||||
if test -z "${PCRE2_MANDATORY}"; then
|
||||
if test -z "${PCRE2_DISABLED}"; then
|
||||
AC_MSG_NOTICE([PCRE2 library was not found])
|
||||
PCRE2_FOUND=0
|
||||
else
|
||||
PCRE2_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([PCRE2 was explicitly referenced but it was not found])
|
||||
PCRE2_FOUND=-1
|
||||
fi
|
||||
else
|
||||
if test -z "${PCRE2_MANDATORY}"; then
|
||||
PCRE2_FOUND=2
|
||||
AC_MSG_NOTICE([PCRE2 is disabled by default.])
|
||||
else
|
||||
PCRE2_FOUND=1
|
||||
AC_MSG_NOTICE([using PCRE2 v${PCRE2_VERSION}])
|
||||
PCRE2_CFLAGS="-DWITH_PCRE2 ${PCRE2_CFLAGS}"
|
||||
PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}"
|
||||
AC_SUBST(PCRE2_VERSION)
|
||||
AC_SUBST(PCRE2_LDADD)
|
||||
AC_SUBST(PCRE2_LIBS)
|
||||
AC_SUBST(PCRE2_LDFLAGS)
|
||||
AC_SUBST(PCRE2_CFLAGS)
|
||||
AC_SUBST(PCRE2_DISPLAY)
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_SUBST(PCRE2_FOUND)
|
||||
|
||||
]) # AC_DEFUN [PROG_PCRE2]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_PCRE2_AT], [
|
||||
path=$1
|
||||
echo "*** LOOKING AT PATH: " ${path}
|
||||
for y in ${PCRE2_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${PCRE2_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
pcre2_lib_path="${path}/"
|
||||
pcre2_lib_name="${z}"
|
||||
pcre2_lib_file="${pcre2_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
pcre2_lib_path="${path}/"
|
||||
pcre2_lib_name="${z}"
|
||||
pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
pcre2_lib_path="${path}/lib/"
|
||||
pcre2_lib_name="${z}"
|
||||
pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
pcre2_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
pcre2_lib_name="${z}"
|
||||
pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then
|
||||
pcre2_lib_path="${path}/lib/i386-linux-gnu/"
|
||||
pcre2_lib_name="${z}"
|
||||
pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$pcre2_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/pcre2.h"; then
|
||||
pcre2_inc_path="${path}/include"
|
||||
elif test -e "${path}/pcre2.h"; then
|
||||
pcre2_inc_path="${path}"
|
||||
elif test -e "${path}/include/pcre2/pcre2.h"; then
|
||||
pcre2_inc_path="${path}/include"
|
||||
fi
|
||||
|
||||
if test -n "${pcre2_lib_path}"; then
|
||||
AC_MSG_NOTICE([PCRE2 library found at: ${pcre2_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${pcre2_inc_path}"; then
|
||||
AC_MSG_NOTICE([PCRE2 headers found at: ${pcre2_inc_path}])
|
||||
fi
|
||||
|
||||
if test -n "${pcre2_lib_path}" -a -n "${pcre2_inc_path}"; then
|
||||
# TODO: Compile a piece of code to check the version.
|
||||
PCRE2_CFLAGS="-I${pcre2_inc_path}"
|
||||
PCRE2_LDADD="-l${pcre2_lib_name}"
|
||||
PCRE2_LDFLAGS="-L${pcre2_lib_path}"
|
||||
PCRE2_DISPLAY="${pcre2_lib_file}, ${pcre2_inc_path}"
|
||||
fi
|
||||
]) # AC_DEFUN [CHECK_FOR_PCRE2_AT]
|
|
@ -1,21 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
git clean -xfdi
|
||||
git submodule foreach --recursive git clean -xfdi
|
||||
|
||||
VERSION=`git describe --tags`
|
||||
DIR_NAME="modsecurity-$VERSION"
|
||||
TAR_NAME="modsecurity-$VERSION.tar.gz"
|
||||
|
||||
MY_DIR=${PWD##*/}
|
||||
./build.sh
|
||||
|
||||
cd ..
|
||||
tar --transform "s/^$MY_DIR/$DIR_NAME/" -cvzf $TAR_NAME --exclude .git $MY_DIR
|
||||
|
||||
sha256sum $TAR_NAME > $TAR_NAME.sha256
|
||||
gpg --detach-sign -a $TAR_NAME
|
||||
|
||||
cd -
|
||||
echo $TAR_NAME ": done."
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
dnl Check for SSDEEP Libraries
|
||||
dnl CHECK_SSDEEP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_SSDEEP],
|
||||
[dnl
|
||||
|
||||
# Possible names for the ssdeep library/package (pkg-config)
|
||||
SSDEEP_POSSIBLE_LIB_NAMES="fuzzy"
|
||||
|
||||
# Possible extensions for the library
|
||||
SSDEEP_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
SSDEEP_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/fuzzy /usr/local/libfuzzy /usr/local /opt /usr /usr/lib64 /opt/local"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
SSDEEP_CFLAGS=""
|
||||
SSDEEP_LDFLAGS=""
|
||||
SSDEEP_LDADD=""
|
||||
SSDEEP_DISPLAY=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
ssdeep,
|
||||
[AS_HELP_STRING([--with-ssdeep=PATH],[Path to ssdeep prefix])]
|
||||
)
|
||||
|
||||
|
||||
if test "x${with_ssdeep}" == "xno"; then
|
||||
AC_DEFINE(HAVE_SSDEEP, 0, [Support for SSDEEP was disabled by the utilization of --without-ssdeep or --with-ssdeep=no])
|
||||
AC_MSG_NOTICE([Support for SSDEEP was disabled by the utilization of --without-ssdeep or --with-ssdeep=no])
|
||||
SSDEEP_DISABLED=yes
|
||||
else
|
||||
if test "x${with_ssdeep}" == "xyes"; then
|
||||
SSDEEP_MANDATORY=yes
|
||||
AC_MSG_NOTICE([SSDEEP support was marked as mandatory by the utilization of --with-ssdeep=yes])
|
||||
else
|
||||
SSDEEP_MANDATORY=no
|
||||
fi
|
||||
for x in ${SSDEEP_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_SSDEEP_AT(${x})
|
||||
if test -n "${SSDEEP_CFLAGS}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
if test -z "${SSDEEP_CFLAGS}"; then
|
||||
if test -z "${SSDEEP_MANDATORY}" || test "x${SSDEEP_MANDATORY}" == "xno"; then
|
||||
if test -z "${SSDEEP_DISABLED}"; then
|
||||
AC_MSG_NOTICE([SSDEEP library was not found])
|
||||
SSDEEP_FOUND=0
|
||||
else
|
||||
SSDEEP_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([SSDEEP was explicitly referenced but it was not found])
|
||||
SSDEEP_FOUND=-1
|
||||
fi
|
||||
else
|
||||
SSDEEP_FOUND=1
|
||||
AC_MSG_NOTICE([using SSDEEP v${SSDEEP_VERSION}])
|
||||
SSDEEP_CFLAGS="-DWITH_SSDEEP ${SSDEEP_CFLAGS}"
|
||||
SSDEEP_DISPLAY="${SSDEEP_LDADD} ${SSDEEP_LDFLAGS}, ${SSDEEP_CFLAGS}"
|
||||
AC_SUBST(SSDEEP_LDFLAGS)
|
||||
AC_SUBST(SSDEEP_LDADD)
|
||||
AC_SUBST(SSDEEP_CFLAGS)
|
||||
AC_SUBST(SSDEEP_DISPLAY)
|
||||
fi
|
||||
|
||||
|
||||
AC_SUBST(SSDEEP_FOUND)
|
||||
|
||||
]) # AC_DEFUN [CHECK_SSDEEP]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_SSDEEP_AT], [
|
||||
path=$1
|
||||
echo "*** LOOKING AT PATH: " ${path}
|
||||
for y in ${SSDEEP_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${SSDEEP_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
ssdeep_lib_path="${path}/"
|
||||
ssdeep_lib_name="${z}"
|
||||
ssdeep_lib_file="${ssdeep_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
ssdeep_lib_path="${path}/"
|
||||
ssdeep_lib_name="${z}"
|
||||
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
ssdeep_lib_path="${path}/lib/"
|
||||
ssdeep_lib_name="${z}"
|
||||
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
ssdeep_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
ssdeep_lib_name="${z}"
|
||||
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then
|
||||
ssdeep_lib_path="${path}/lib/i386-linux-gnu/"
|
||||
ssdeep_lib_name="${z}"
|
||||
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$ssdeep_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/fuzzy.h"; then
|
||||
ssdeep_inc_path="${path}/include"
|
||||
elif test -e "${path}/fuzzy.h"; then
|
||||
ssdeep_inc_path="${path}"
|
||||
elif test -e "${path}/include/fuzzy/fuzzy.h"; then
|
||||
ssdeep_inc_path="${path}/include"
|
||||
fi
|
||||
|
||||
if test -n "${ssdeep_lib_path}"; then
|
||||
AC_MSG_NOTICE([SSDEEP library found at: ${ssdeep_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${ssdeep_inc_path}"; then
|
||||
AC_MSG_NOTICE([SSDEEP headers found at: ${ssdeep_inc_path}])
|
||||
fi
|
||||
|
||||
if test -n "${ssdeep_lib_path}" -a -n "${ssdeep_inc_path}"; then
|
||||
# TODO: Compile a piece of code to check the version.
|
||||
SSDEEP_CFLAGS="-I${ssdeep_inc_path}"
|
||||
SSDEEP_LDADD="-l${ssdeep_lib_name}"
|
||||
SSDEEP_LDFLAGS="-L${ssdeep_lib_path}"
|
||||
SSDEEP_DISPLAY="${ssdeep_lib_file}, ${ssdeep_inc_path}"
|
||||
fi
|
||||
]) # AC_DEFUN [CHECK_FOR_SSDEEP_AT]
|
||||
|
||||
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
dnl Check for YAJL Libraries
|
||||
dnl CHECK_YAJL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([PROG_YAJL], [
|
||||
|
||||
# Possible names for the yajl library/package (pkg-config)
|
||||
YAJL_POSSIBLE_LIB_NAMES="yajl2 yajl"
|
||||
|
||||
# Possible extensions for the library
|
||||
YAJL_POSSIBLE_EXTENSIONS="so la sl dll dylib"
|
||||
|
||||
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||
YAJL_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/libyajl /usr/local/yajl /usr/local /opt/libyajl /opt/yajl /opt /usr /usr/lib64"
|
||||
|
||||
# Variables to be set by this very own script.
|
||||
YAJL_VERSION=""
|
||||
YAJL_CFLAGS=""
|
||||
YAJL_CPPFLAGS=""
|
||||
YAJL_LDADD=""
|
||||
YAJL_LDFLAGS=""
|
||||
|
||||
AC_ARG_WITH(
|
||||
yajl,
|
||||
[AS_HELP_STRING([--with-yajl=PATH],[Path to yajl prefix or config script])]
|
||||
)
|
||||
|
||||
if test "x${with_yajl}" == "xno"; then
|
||||
AC_DEFINE(HAVE_YAJL, 0, [Support for YAJL was disabled by the utilization of --without-yajl or --with-yajl=no])
|
||||
AC_MSG_NOTICE([Support for YAJL was disabled by the utilization of --without-yajl or --with-yajl=no])
|
||||
YAJL_DISABLED=yes
|
||||
else
|
||||
if test "x${with_yajl}" == "xyes"; then
|
||||
YAJL_MANDATORY=yes
|
||||
AC_MSG_NOTICE([YAJL support was marked as mandatory by the utilization of --with-yajl=yes])
|
||||
fi
|
||||
# for x in ${YAJL_POSSIBLE_LIB_NAMES}; do
|
||||
# CHECK_FOR_YAJL_AT(${x})
|
||||
# if test -n "${YAJL_VERSION}"; then
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
|
||||
# if test "x${with_yajl}" != "xyes" or test "x${with_yajl}" == "xyes"; then
|
||||
if test "x${with_yajl}" == "x" || test "x${with_yajl}" == "xyes"; then
|
||||
# Nothing about YAJL was informed, using the pkg-config to figure things out.
|
||||
if test -n "${PKG_CONFIG}"; then
|
||||
YAJL_PKG_NAME=""
|
||||
for x in ${YAJL_POSSIBLE_LIB_NAMES}; do
|
||||
if ${PKG_CONFIG} --exists ${x}; then
|
||||
YAJL_PKG_NAME="$x"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_MSG_NOTICE([Nothing about YAJL was informed during the configure phase. Trying to detect it on the platform...])
|
||||
if test -n "${YAJL_PKG_NAME}"; then
|
||||
# Package was found using the pkg-config scripts
|
||||
YAJL_VERSION="`${PKG_CONFIG} ${YAJL_PKG_NAME} --modversion`"
|
||||
YAJL_CFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --cflags`"
|
||||
YAJL_LDADD="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-l`"
|
||||
YAJL_LDFLAGS="`${PKG_CONFIG} ${YAJL_PKG_NAME} --libs-only-L --libs-only-other`"
|
||||
YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}"
|
||||
else
|
||||
# If pkg-config did not find anything useful, go over file lookup.
|
||||
for x in ${YAJL_POSSIBLE_LIB_NAMES}; do
|
||||
CHECK_FOR_YAJL_AT(${x})
|
||||
if test -n "${YAJL_VERSION}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "x${with_yajl}" != "x"; then
|
||||
# An specific path was informed, lets check.
|
||||
YAJL_MANDATORY=yes
|
||||
CHECK_FOR_YAJL_AT(${with_yajl})
|
||||
fi
|
||||
# fi
|
||||
fi
|
||||
|
||||
if test -z "${YAJL_LDADD}"; then
|
||||
if test -z "${YAJL_MANDATORY}"; then
|
||||
if test -z "${YAJL_DISABLED}"; then
|
||||
AC_MSG_NOTICE([YAJL library was not found])
|
||||
YAJL_FOUND=0
|
||||
else
|
||||
YAJL_FOUND=2
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([YAJL was explicitly referenced but it was not found])
|
||||
YAJL_FOUND=-1
|
||||
fi
|
||||
else
|
||||
YAJL_FOUND=1
|
||||
AC_MSG_NOTICE([using YAJL v${YAJL_VERSION}])
|
||||
YAJL_CFLAGS="-DWITH_YAJL ${YAJL_CFLAGS}"
|
||||
YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}"
|
||||
AC_SUBST(YAJL_VERSION)
|
||||
AC_SUBST(YAJL_LDADD)
|
||||
AC_SUBST(YAJL_LIBS)
|
||||
AC_SUBST(YAJL_LDFLAGS)
|
||||
AC_SUBST(YAJL_CFLAGS)
|
||||
AC_SUBST(YAJL_DISPLAY)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
AC_SUBST(YAJL_FOUND)
|
||||
|
||||
]) # AC_DEFUN [PROG_YAJL]
|
||||
|
||||
|
||||
AC_DEFUN([CHECK_FOR_YAJL_AT], [
|
||||
path=$1
|
||||
for y in ${YAJL_POSSIBLE_EXTENSIONS}; do
|
||||
for z in ${YAJL_POSSIBLE_LIB_NAMES}; do
|
||||
if test -e "${path}/${z}.${y}"; then
|
||||
yajl_lib_path="${path}/"
|
||||
yajl_lib_name="${z}"
|
||||
yajl_lib_file="${yajl_lib_path}/${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib${z}.${y}"; then
|
||||
yajl_lib_path="${path}/"
|
||||
yajl_lib_name="${z}"
|
||||
yajl_lib_file="${yajl_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||
yajl_lib_path="${path}/lib/"
|
||||
yajl_lib_name="${z}"
|
||||
yajl_lib_file="${yajl_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||
yajl_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||
yajl_lib_name="${z}"
|
||||
yajl_lib_file="${yajl_lib_path}/lib${z}.${y}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$yajl_lib_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -e "${path}/include/yajl_parse.h"; then
|
||||
yajl_inc_path="${path}/include"
|
||||
elif test -e "${path}/yajl_parse.h"; then
|
||||
yajl_inc_path="${path}"
|
||||
elif test -e "${path}/include/yajl/yajl_parse.h"; then
|
||||
yajl_inc_path="${path}/include"
|
||||
fi
|
||||
|
||||
if test -n "${yajl_lib_path}"; then
|
||||
AC_MSG_NOTICE([YAJL library found at: ${yajl_lib_file}])
|
||||
fi
|
||||
|
||||
if test -n "${yajl_inc_path}"; then
|
||||
AC_MSG_NOTICE([YAJL headers found at: ${yajl_inc_path}])
|
||||
fi
|
||||
|
||||
if test -n "${yajl_lib_path}" -a -n "${yajl_inc_path}"; then
|
||||
# TODO: Compile a piece of code to check the version.
|
||||
YAJL_CFLAGS="-I${yajl_inc_path}"
|
||||
YAJL_LDADD="-l${yajl_lib_name}"
|
||||
YAJL_LDFLAGS="-L${yajl_lib_path}"
|
||||
YAJL_DISPLAY="${yajl_lib_file}, ${yajl_inc_path}"
|
||||
fi
|
||||
]) # AC_DEFUN [CHECK_FOR_YAJL_AT]
|
|
@ -1,639 +0,0 @@
|
|||
# ModSecurity configure.ac
|
||||
|
||||
|
||||
# Get the hash of the last commit, to be used if it is not an
|
||||
# official release.
|
||||
AC_DEFUN([MSC_GIT_HASH], m4_esyscmd_s(git log -1 --format="%h" --abbrev-commit))
|
||||
AC_DEFUN([MSC_MAJOR], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_MAJOR " | awk {'print $3'} | sed 's/\"//g'))
|
||||
AC_DEFUN([MSC_MINOR], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_MINOR " | awk {'print $3'} | sed 's/\"//g'))
|
||||
AC_DEFUN([MSC_PATCHLEVEL], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_PATCHLEVEL " | awk {'print $3'} | sed 's/\"//g'))
|
||||
AC_DEFUN([MSC_TAG], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_FTAG " | awk {'print $3'} | sed 's/\"//g'))
|
||||
|
||||
|
||||
# Version definition to be further used by AC_INIT and
|
||||
# .so file naming.
|
||||
m4_define([msc_version_major], [MSC_MAJOR])
|
||||
m4_define([msc_version_minor], [MSC_MINOR])
|
||||
m4_define([msc_version_patchlevel], [MSC_PATCHLEVEL])
|
||||
|
||||
m4_define([msc_version_c_plus_a], [m4_eval(msc_version_major + msc_version_minor)])
|
||||
|
||||
|
||||
m4_define([msc_version],
|
||||
[msc_version_major.msc_version_minor])
|
||||
|
||||
m4_define([msc_version_with_patchlevel],
|
||||
[msc_version_major.msc_version_minor.msc_version_patchlevel])
|
||||
|
||||
m4_define([msc_version_git],
|
||||
[m4_esyscmd_s(git describe)])
|
||||
|
||||
m4_define([msc_version_info],
|
||||
[msc_version_c_plus_a:msc_version_patchlevel:msc_version_minor])
|
||||
|
||||
|
||||
# Project Information
|
||||
AC_INIT([modsecurity], [3.0], [security@modsecurity.org])
|
||||
|
||||
|
||||
# General definitions
|
||||
AC_CONFIG_MACRO_DIR([build])
|
||||
AC_PREFIX_DEFAULT([/usr/local/modsecurity])
|
||||
|
||||
|
||||
# General automake options.
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||
|
||||
|
||||
# Check for dependencies (C++, AR, Lex, Yacc and Make)
|
||||
AC_PROG_CXX
|
||||
AM_PROG_AR
|
||||
AC_PROG_MAKE_SET
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
|
||||
# Check if the compiler is c++11 compatible.
|
||||
# AX_CXX_COMPILE_STDCXX_11(,mandatory)
|
||||
|
||||
# Check for libinjection
|
||||
if ! test -f "${srcdir}/others/libinjection/src/libinjection_html5.c"; then
|
||||
AC_MSG_ERROR([\
|
||||
|
||||
|
||||
libInjection was not found within ModSecurity source directory.
|
||||
|
||||
libInjection code is available as part of ModSecurity source code in a format
|
||||
of a git-submodule. git-submodule allow us to specify the correct version of
|
||||
libInjection and still uses the libInjection repository to download it.
|
||||
|
||||
You can download libInjection using git:
|
||||
|
||||
$ git submodule init
|
||||
$ git submodule update
|
||||
|
||||
])
|
||||
fi
|
||||
# Libinjection version
|
||||
AC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd "others/libinjection" && git describe && cd ../..))
|
||||
|
||||
# SecLang test version
|
||||
AC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd "test/test-cases/secrules-language-tests" && git log -1 --format="%h" --abbrev-commit && cd ../../..))
|
||||
|
||||
|
||||
# Check for yajl
|
||||
PROG_YAJL
|
||||
|
||||
AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""])
|
||||
|
||||
# Check for LibGeoIP
|
||||
PROG_GEOIP
|
||||
AM_CONDITIONAL([GEOIP_CFLAGS], [test "GEOIP_CFLAGS" != ""])
|
||||
|
||||
# Check for MaxMind
|
||||
PROG_MAXMIND
|
||||
AM_CONDITIONAL([MAXMIND_CFLAGS], [test "MAXMIND_CFLAGS" != ""])
|
||||
|
||||
|
||||
# Check for LMDB
|
||||
PROG_LMDB
|
||||
AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""])
|
||||
|
||||
# Check for SSDEEP
|
||||
CHECK_SSDEEP
|
||||
AM_CONDITIONAL([SSDEEP_CFLAGS], [test "SSDEEP_CFLAGS" != ""])
|
||||
|
||||
# Check for LUA
|
||||
CHECK_LUA
|
||||
AM_CONDITIONAL([LUA_CFLAGS], [test "LUA_CFLAGS" != ""])
|
||||
|
||||
|
||||
#
|
||||
# Check for curl
|
||||
#
|
||||
CHECK_CURL
|
||||
|
||||
if ! test -z "${CURL_VERSION}"; then
|
||||
AC_DEFINE([MSC_WITH_CURL], [1], [Define if libcurl is available])
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Check for LibXML
|
||||
#
|
||||
CHECK_LIBXML2
|
||||
|
||||
|
||||
#
|
||||
# Check for libpcre
|
||||
#
|
||||
CHECK_PCRE
|
||||
|
||||
|
||||
#
|
||||
# Check for pcre2
|
||||
#
|
||||
PROG_PCRE2
|
||||
AM_CONDITIONAL([PCRE2_CFLAGS], [test "PCRE2_CFLAGS" != ""])
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([string])
|
||||
AC_CHECK_HEADERS([iostream])
|
||||
AC_CHECK_HEADERS([sys/utsname.h])
|
||||
|
||||
|
||||
# ??
|
||||
LT_INIT([dlopen])
|
||||
|
||||
# Identify platform
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
case $host in
|
||||
*-*-aix*)
|
||||
echo "Checking platform... Identified as AIX"
|
||||
AC_DEFINE([AIX], [1], [Define if the operating system is AIX])
|
||||
PLATFORM="AIX"
|
||||
;;
|
||||
*-*-hpux*)
|
||||
echo "Checking platform... Identified as HPUX"
|
||||
AC_DEFINE([HPUX], [1], [Define if the operating system is HPUX])
|
||||
PLATFORM="HPUX"
|
||||
;;
|
||||
*-*-darwin*)
|
||||
echo "Checking platform... Identified as Macintosh OS X"
|
||||
AC_DEFINE([MACOSX], [1], [Define if the operating system is Macintosh OSX])
|
||||
PLATFORM="MacOSX"
|
||||
;;
|
||||
*-*-linux* | *-*uclinux*)
|
||||
echo "Checking platform... Identified as Linux"
|
||||
AC_DEFINE([LINUX], [1], [Define if the operating system is LINUX])
|
||||
PLATFORM="Linux"
|
||||
;;
|
||||
*-*-solaris*)
|
||||
echo "Checking platform... Identified as Solaris"
|
||||
AC_DEFINE([SOLARIS], [1], [Define if the operating system is SOLARIS])
|
||||
PLATFORM="Solaris"
|
||||
;;
|
||||
*-*-freebsd*)
|
||||
echo "Checking platform... Identified as FreeBSD"
|
||||
AC_DEFINE([FREEBSD], [1], [Define if the operating system is FREEBSD])
|
||||
PLATFORM="FreeBSD"
|
||||
;;
|
||||
*-*-netbsd*)
|
||||
echo "Checking platform... Identified as NetBSD"
|
||||
AC_DEFINE([NETBSD], [1], [Define if the operating system is NETBSD])
|
||||
PLATFORM="NetBSD"
|
||||
;;
|
||||
*-*-openbsd*)
|
||||
echo "Checking platform... Identified as OpenBSD"
|
||||
AC_DEFINE([OPENBSD], [1], [Define if the operating system is OPENBSD])
|
||||
PLATFORM="OpenBSD"
|
||||
;;
|
||||
*-*-kfreebsd*)
|
||||
echo "Checking platform... Identified as kFreeBSD, treating as linux"
|
||||
AC_DEFINE([FREEBSD], [1], [Define if the operating system is FREEBSD])
|
||||
PLATFORM="kFreeBSD"
|
||||
;;
|
||||
*-*-dragonfly*)
|
||||
echo "Checking platform... Identified as DragonFlyBSD, treating as linux"
|
||||
AC_DEFINE([DRAGONFLY], [1], [Define if the operating system is DRAGONFLY])
|
||||
PLATFORM="DragonFly"
|
||||
;;
|
||||
*-*-gnu*.*)
|
||||
echo "Checking platform... Identified as HURD, treating as linux"
|
||||
AC_DEFINE([LINUX], [1], [Define if the operating system is LINUX])
|
||||
PLATFORM="HURD"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown CANONICAL_HOST $host"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Variables to be used inside the Makefile.am files.
|
||||
MSC_BASE_DIR=`pwd`
|
||||
AC_SUBST([MSC_BASE_DIR])
|
||||
|
||||
MSC_VERSION_INFO=msc_version_info
|
||||
AC_SUBST([MSC_VERSION_INFO])
|
||||
|
||||
MSC_VERSION_WITH_PATCHLEVEL=msc_version_with_patchlevel
|
||||
AC_SUBST([MSC_VERSION_WITH_PATCHLEVEL])
|
||||
|
||||
MSC_VERSION=msc_version
|
||||
AC_SUBST([MSC_VERSION])
|
||||
|
||||
MSC_GIT_VERSION=msc_version_git
|
||||
AC_SUBST([MSC_GIT_VERSION])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(debug-logs,
|
||||
[AS_HELP_STRING([--disable-debug-logs],[Turn off the SecDebugLog feature])],
|
||||
|
||||
[case "${enableval}" in
|
||||
yes) debugLogs=true ;;
|
||||
no) debugLogs=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug-logs) ;;
|
||||
esac],
|
||||
|
||||
[debugLogs=true]
|
||||
)
|
||||
if test "$debugLogs" != "true"; then
|
||||
MODSEC_NO_LOGS="-DNO_LOGS=1"
|
||||
AC_SUBST(MODSEC_NO_LOGS)
|
||||
fi
|
||||
|
||||
|
||||
# Fuzzer
|
||||
AC_ARG_ENABLE(afl-fuzz,
|
||||
[AS_HELP_STRING([--enable-afl-fuzz],[Turn on the afl fuzzer compilation utilities])],
|
||||
|
||||
[case "${enableval}" in
|
||||
yes) aflFuzzer=true ;;
|
||||
no) aflFuzzer=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-afl-fuzz) ;;
|
||||
esac],
|
||||
|
||||
[aflFuzzer=false]
|
||||
)
|
||||
|
||||
# Examples
|
||||
AC_ARG_ENABLE(examples,
|
||||
[AS_HELP_STRING([--enable-examples],[Turn on the examples compilation (default option)])],
|
||||
|
||||
[case "${enableval}" in
|
||||
yes) buildExamples=true ;;
|
||||
no) buildExamples=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-examples) ;;
|
||||
esac],
|
||||
|
||||
[buildExamples=true]
|
||||
)
|
||||
|
||||
# Parser
|
||||
AC_ARG_ENABLE(parser-generation,
|
||||
[AS_HELP_STRING([--enable-parser-generation],[Enables parser generation during the build])],
|
||||
|
||||
[case "${enableval}" in
|
||||
yes) buildParser=true ;;
|
||||
no) buildParser=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-parser-generation) ;;
|
||||
esac],
|
||||
|
||||
[buildParser=false]
|
||||
)
|
||||
|
||||
# Mutex
|
||||
AC_ARG_ENABLE(mutex-on-pm,
|
||||
[AS_HELP_STRING([--enable-mutex-on-pm],[Treats pm operations as a critical section])],
|
||||
|
||||
[case "${enableval}" in
|
||||
yes) mutexPm=true ;;
|
||||
no) mutexPm=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mutex-on-pm) ;;
|
||||
esac],
|
||||
|
||||
[mutexPm=false]
|
||||
)
|
||||
if test "$mutexPm" == "true"; then
|
||||
MODSEC_MUTEX_ON_PM="-DMUTEX_ON_PM=1"
|
||||
AC_SUBST(MODSEC_MUTEX_ON_PM)
|
||||
fi
|
||||
|
||||
|
||||
if test $buildParser = true; then
|
||||
AC_PROG_YACC
|
||||
AC_PROG_LEX
|
||||
AC_PATH_PROG([FLEX], [flex])
|
||||
test "x$FLEX" = "x" && AC_MSG_ERROR([flex is needed to build ModSecurity])
|
||||
|
||||
AC_PATH_PROG([BISON], [bison])
|
||||
test "x$BISON" = "x" && AC_MSG_ERROR([bison is needed to build ModSecurity])
|
||||
|
||||
AC_PATH_PROG([YACC_INST], $YACC)
|
||||
if test ! -f "$srcdir/gram.c"; then
|
||||
if test -z "$YACC_INST"; then
|
||||
AC_MSG_ERROR([yacc not found - unable to compile ModSecurity])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Decide if we want to build the tests or not.
|
||||
# buildTestUtilities=false
|
||||
# if test "x$YAJL_FOUND" = "x1"; then
|
||||
# Regression tests will not be able to run without the logging support.
|
||||
# But we still have the unit tests.
|
||||
# if test "$debugLogs" = "true"; then
|
||||
# buildTestUtilities=true
|
||||
# fi
|
||||
# fi
|
||||
|
||||
|
||||
AM_CONDITIONAL([TEST_UTILITIES], [test $buildTestUtilities = true])
|
||||
if test $buildTestUtilities = true; then
|
||||
if test $debugLogs = true; then
|
||||
if test -f ./test/test-list.sh; then
|
||||
TEST_CASES=`./test/test-list.sh`
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([EXAMPLES], [test $buildExamples = true])
|
||||
AM_CONDITIONAL([BUILD_PARSER], [test $buildParser = true])
|
||||
AM_CONDITIONAL([USE_MUTEX_ON_PM], [test $mutexPm = true])
|
||||
|
||||
|
||||
# General link options
|
||||
if test "$PLATFORM" != "MacOSX" -a "$PLATFORM" != "OpenBSD"; then
|
||||
GLOBAL_LDADD="-lrt "
|
||||
fi
|
||||
|
||||
if test "$aflFuzzer" == "true"; then
|
||||
FUZZ_CPPCFLAGS="-fsanitize=address -fsanitize-coverage=4 "
|
||||
GLOBAL_LDADD="$GLOBAL_LDADD -fsanitize=address "
|
||||
GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $FUZZ_CPPCFLAGS"
|
||||
$buildExamples = false
|
||||
fi
|
||||
AC_SUBST(GLOBAL_LDADD)
|
||||
AC_SUBST(GLOBAL_CPPFLAGS)
|
||||
|
||||
AM_CONDITIONAL([AFL_FUZZER], [test $aflFuzzer = true])
|
||||
|
||||
GLOBAL_CFLAGS=""
|
||||
AC_SUBST(GLOBAL_CFLAGS)
|
||||
|
||||
# Files to be generated via autotools.
|
||||
AC_CONFIG_FILES([\
|
||||
modsecurity.pc \
|
||||
Makefile \
|
||||
doc/Makefile \
|
||||
src/Makefile \
|
||||
others/Makefile \
|
||||
tools/Makefile \
|
||||
tools/rules-check/Makefile
|
||||
])
|
||||
|
||||
AM_COND_IF([TEST_UTILITIES],
|
||||
[AC_CONFIG_FILES([test/Makefile test/benchmark/Makefile])])
|
||||
|
||||
AM_COND_IF([EXAMPLES],
|
||||
[AC_CONFIG_FILES([ \
|
||||
examples/Makefile \
|
||||
examples/simple_example_using_c/Makefile \
|
||||
examples/multiprocess_c/Makefile \
|
||||
examples/reading_logs_with_offset/Makefile \
|
||||
examples/reading_logs_via_rule_message/Makefile \
|
||||
examples/using_bodies_in_chunks/Makefile \
|
||||
])])
|
||||
|
||||
AM_COND_IF([AFL_FUZZER],
|
||||
[AC_CONFIG_FILES([test/fuzzer/Makefile])])
|
||||
|
||||
AM_COND_IF([BUILD_PARSER],
|
||||
[AC_CONFIG_FILES([src/parser/Makefile])])
|
||||
|
||||
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
|
||||
|
||||
# Doxygen support
|
||||
DX_HTML_FEATURE(ON)
|
||||
DX_CHM_FEATURE(OFF)
|
||||
DX_CHI_FEATURE(OFF)
|
||||
DX_MAN_FEATURE(OFF)
|
||||
DX_RTF_FEATURE(OFF)
|
||||
DX_XML_FEATURE(OFF)
|
||||
DX_PDF_FEATURE(OFF)
|
||||
DX_PS_FEATURE(OFF)
|
||||
|
||||
DX_INIT_DOXYGEN([ModSecurity],[doc/doxygen.cfg])
|
||||
|
||||
# make check-valgrind
|
||||
AX_VALGRIND_DFLT([sgcheck], [off])
|
||||
AX_VALGRIND_CHECK
|
||||
|
||||
# Generate the files.
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
# Print a fancy summary
|
||||
echo " "
|
||||
echo " "
|
||||
echo "ModSecurity - ${MSC_GIT_VERSION} for $PLATFORM"
|
||||
echo " "
|
||||
echo " Mandatory dependencies"
|
||||
echo -n " + libInjection ...."
|
||||
echo LIBINJECTION_VERSION
|
||||
echo -n " + SecLang tests ...."
|
||||
echo SECLANG_TEST_VERSION
|
||||
|
||||
echo " "
|
||||
echo " Optional dependencies"
|
||||
|
||||
|
||||
|
||||
## GeoIP - MaxMind
|
||||
if test "x$GEOIP_FOUND" = "x0" && test "x$MAXMIND_FOUND" = "x0"; then
|
||||
echo " + GeoIP/MaxMind ....not found"
|
||||
fi
|
||||
if test "x$GEOIP_FOUND" = "x1" || test "x$MAXMIND_FOUND" = "x1"; then
|
||||
echo -n " + GeoIP/MaxMind ....found "
|
||||
echo ""
|
||||
if test "x$MAXMIND_FOUND" = "x1"; then
|
||||
echo " * (MaxMind) v${MAXMIND_VERSION}"
|
||||
echo " ${MAXMIND_DISPLAY}"
|
||||
fi
|
||||
if test "x$GEOIP_FOUND" = "x1"; then
|
||||
echo " * (GeoIP) v${GEOIP_VERSION}"
|
||||
echo " ${GEOIP_DISPLAY}"
|
||||
fi
|
||||
fi
|
||||
if test "x$GEOIP_FOUND" = "x2" && test "x$MAXMIND_FOUND" = "x2"; then
|
||||
echo " + GeoIP/MaxMind ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
## LibCurl
|
||||
if test "x$CURL_FOUND" = "x0"; then
|
||||
echo " + LibCURL ....not found"
|
||||
fi
|
||||
if test "x$CURL_FOUND" = "x1"; then
|
||||
echo -n " + LibCURL ....found "
|
||||
if ! test "x$CURL_VERSION" = "x"; then
|
||||
echo "v${CURL_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${CURL_DISPLAY}"
|
||||
fi
|
||||
if test "x$CURL_FOUND" = "x2"; then
|
||||
echo " + LibCURL ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
## YAJL
|
||||
if test "x$YAJL_FOUND" = "x0"; then
|
||||
echo " + YAJL ....not found"
|
||||
fi
|
||||
if test "x$YAJL_FOUND" = "x1"; then
|
||||
echo -n " + YAJL ....found "
|
||||
if ! test "x$YAJL_VERSION" = "x"; then
|
||||
echo "v${YAJL_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${YAJL_DISPLAY}"
|
||||
fi
|
||||
if test "x$YAJL_FOUND" = "x2"; then
|
||||
echo " + YAJL ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
## LMDB
|
||||
if test "x$LMDB_FOUND" = "x0"; then
|
||||
echo " + LMDB ....not found"
|
||||
fi
|
||||
if test "x$LMDB_FOUND" = "x1"; then
|
||||
echo -n " + LMDB ....found "
|
||||
if ! test "x$LMDB_VERSION" = "x"; then
|
||||
echo "v${LMDB_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${LMDB_DISPLAY}"
|
||||
fi
|
||||
if test "x$LMDB_FOUND" = "x2"; then
|
||||
echo " + LMDB ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
## libxml2
|
||||
if test "x$LIBXML2_FOUND" = "x0"; then
|
||||
echo " + LibXML2 ....not found"
|
||||
fi
|
||||
if test "x$LIBXML2_FOUND" = "x1"; then
|
||||
echo -n " + LibXML2 ....found "
|
||||
if ! test "x$LIBXML2_VERSION" = "x"; then
|
||||
echo "v${LIBXML2_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${LIBXML2_DISPLAY}"
|
||||
fi
|
||||
if test "x$LIBXML2_FOUND" = "x2"; then
|
||||
echo " + LibXML2 ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
## SSDEEP
|
||||
if test "x$SSDEEP_FOUND" = "x0"; then
|
||||
echo " + SSDEEP ....not found"
|
||||
fi
|
||||
if test "x$SSDEEP_FOUND" = "x1"; then
|
||||
echo -n " + SSDEEP ....found "
|
||||
if ! test "x$SSDEEP_VERSION" = "x"; then
|
||||
echo "v${SSDEEP_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${SSDEEP_DISPLAY}"
|
||||
fi
|
||||
if test "x$SSDEEP_FOUND" = "x2"; then
|
||||
echo " + SSDEEP ....disabled"
|
||||
fi
|
||||
|
||||
## LUA
|
||||
if test "x$LUA_FOUND" = "x0"; then
|
||||
echo " + LUA ....not found"
|
||||
fi
|
||||
if test "x$LUA_FOUND" = "x1"; then
|
||||
echo -n " + LUA ....found "
|
||||
if ! test "x$LUA_VERSION" = "x"; then
|
||||
echo "v${LUA_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${LUA_DISPLAY}"
|
||||
fi
|
||||
if test "x$LUA_FOUND" = "x2"; then
|
||||
echo " + LUA ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
## PCRE2
|
||||
if test "x$PCRE2_FOUND" = "x0"; then
|
||||
echo " + PCRE2 ....not found"
|
||||
fi
|
||||
if test "x$PCRE2_FOUND" = "x1"; then
|
||||
echo -n " + PCRE2 ....found "
|
||||
if ! test "x$PCRE2_VERSION" = "x"; then
|
||||
echo "v${PCRE2_VERSION}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
echo " ${PCRE2_DISPLAY}"
|
||||
fi
|
||||
if test "x$PCRE2_FOUND" = "x2"; then
|
||||
echo " + PCRE2 ....disabled"
|
||||
fi
|
||||
|
||||
echo " "
|
||||
echo " Other Options"
|
||||
if test $buildTestUtilities = true; then
|
||||
if test $debugLogs = true; then
|
||||
echo " + Test Utilities ....enabled"
|
||||
else
|
||||
echo " + Test Utilities ....partially"
|
||||
fi
|
||||
else
|
||||
echo " + Test Utilities ....disabled"
|
||||
fi
|
||||
if test $debugLogs = true; then
|
||||
echo " + SecDebugLog ....enabled"
|
||||
else
|
||||
echo " + SecDebugLog ....disabled"
|
||||
fi
|
||||
|
||||
if test "$aflFuzzer" = "true"; then
|
||||
echo " + afl fuzzer ....enabled"
|
||||
echo " ($FUZZ_CPPCFLAGS)"
|
||||
else
|
||||
echo " + afl fuzzer ....disabled"
|
||||
fi
|
||||
|
||||
if test "$buildExamples" = "true"; then
|
||||
echo " + library examples ....enabled"
|
||||
else
|
||||
echo " + library examples ....disabled"
|
||||
fi
|
||||
|
||||
if test "$buildParser" = "true"; then
|
||||
echo " + Building parser ....enabled"
|
||||
else
|
||||
echo " + Building parser ....disabled"
|
||||
fi
|
||||
|
||||
if test "$mutexPm" = "true"; then
|
||||
echo " + Treating pm operations as critical section ....enabled"
|
||||
else
|
||||
echo " + Treating pm operations as critical section ....disabled"
|
||||
fi
|
||||
|
||||
|
||||
echo " "
|
||||
|
||||
|
||||
if test "$aflFuzzer" = "true"; then
|
||||
echo "WARNING: afl fuzzer was enabled. Make sure you are using the"
|
||||
echo " 'afl-clang-fast' as the compiler, otherwise the compilation"
|
||||
echo " will fail."
|
||||
echo " "
|
||||
echo " You can set the compiler using:"
|
||||
echo " "
|
||||
echo " $ export CXX=afl-clang-fast++ "
|
||||
echo " $ export CC=afl-clang-fast "
|
||||
echo " "
|
||||
fi
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
--- /dev/null
|
||||
+++ /dev/null
|
||||
@@ -322,12 +322,12 @@
|
||||
|
||||
# Decide if we want to build the tests or not.
|
||||
-buildTestUtilities=false
|
||||
-if test "x$YAJL_FOUND" = "x1"; then
|
||||
+# buildTestUtilities=false
|
||||
+# if test "x$YAJL_FOUND" = "x1"; then
|
||||
# Regression tests will not be able to run without the logging support.
|
||||
# But we still have the unit tests.
|
||||
# if test "$debugLogs" = "true"; then
|
||||
- buildTestUtilities=true
|
||||
+# buildTestUtilities=true
|
||||
# fi
|
||||
-fi
|
||||
+# fi
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
ACLOCAL_AMFLAGS = -I build
|
||||
|
||||
# Doxygen support
|
||||
# include $(top_srcdir)/build/ax_prog_doxygen.m4
|
||||
|
||||
# distribution of the Doxygen configuration file
|
||||
EXTRA_DIST = \
|
||||
doxygen.cfg
|
||||
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
doxygen_sqlite3.db \
|
||||
html \
|
||||
latex
|
||||
|
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
|
@ -1,21 +0,0 @@
|
|||
|
||||
ACLOCAL_AMFLAGS = -I build
|
||||
|
||||
|
||||
SUBDIRS = \
|
||||
multiprocess_c \
|
||||
reading_logs_with_offset \
|
||||
reading_logs_via_rule_message \
|
||||
simple_example_using_c \
|
||||
using_bodies_in_chunks
|
||||
|
||||
pkginclude_HEADERS = \
|
||||
reading_logs_via_rule_message/reading_logs_via_rule_message.h
|
||||
|
||||
# make clean
|
||||
CLEANFILES =
|
||||
|
||||
# make maintainer-clean
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
|
||||
noinst_PROGRAMS = multi
|
||||
|
||||
multi_SOURCES = \
|
||||
multi.c
|
||||
|
||||
multi_LDADD = \
|
||||
$(SSDEEP_LDADD) \
|
||||
$(LUA_LDADD) \
|
||||
$(MAXMIND_LDADD) \
|
||||
$(GLOBAL_LDADD)
|
||||
|
||||
multi_LDFLAGS = \
|
||||
-L$(top_builddir)/src/.libs/ \
|
||||
$(GEOIP_LDFLAGS) \
|
||||
-lmodsecurity \
|
||||
-lpthread \
|
||||
-lm \
|
||||
-lstdc++ \
|
||||
$(LUA_LDFLAGS) \
|
||||
$(SSDEEP_LDFLAGS) \
|
||||
$(MAXMIND_LDFLAGS) \
|
||||
$(YAJL_LDFLAGS)
|
||||
|
||||
multi_CFLAGS = \
|
||||
-I$(top_builddir)/headers \
|
||||
-I$(top_builddir) \
|
||||
$(GLOBAL_CFLAGS)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
SecDebugLog /dev/stdout
|
||||
SecDebugLogLevel 9
|
||||
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent ".*" "id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}"
|
||||
|
||||
SecAction "phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent ".*" "id:2,phase:2,setvar:ip.auth_attempt=+1"
|
||||
|
||||
SecRule ARGS:foo "herewego" "id:3,phase:2,setvar:ip.foo=bar"
|
||||
SecRule IP "bar" "id:4,phase:2"
|
||||
SecRule IP:auth_attempt "bar" "id:5,phase:2"
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <modsecurity/modsecurity.h>
|
||||
#include <modsecurity/transaction.h>
|
||||
#include <modsecurity/rules_set.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
#define FORKS 5
|
||||
#define REQUESTS_PER_PROCESS 100
|
||||
|
||||
|
||||
char main_rule_uri[] = "basic_rules.conf";
|
||||
RulesSet *rules = NULL;
|
||||
ModSecurity *modsec = NULL;
|
||||
|
||||
|
||||
void process_special_request (int j) {
|
||||
Transaction *transaction;
|
||||
transaction = msc_new_transaction(modsec, rules, NULL);
|
||||
|
||||
msc_process_connection(transaction, "127.0.0.1", 12345, "127.0.0.1", 80);
|
||||
msc_process_uri(transaction,
|
||||
"http://www.modsecurity.org/test?foo=herewego",
|
||||
"GET", "1.1");
|
||||
msc_add_request_header(transaction,
|
||||
(const unsigned char *) "User-Agent",
|
||||
(const unsigned char *) "Basic ModSecurity example");
|
||||
msc_process_request_headers(transaction);
|
||||
msc_process_request_body(transaction);
|
||||
msc_add_response_header(transaction,
|
||||
(const unsigned char *) "Content-type",
|
||||
(const unsigned char *) "text/html");
|
||||
msc_process_response_headers(transaction, 200, "HTTP 1.0");
|
||||
msc_process_response_body(transaction);
|
||||
msc_process_logging(transaction);
|
||||
msc_transaction_cleanup(transaction);
|
||||
}
|
||||
|
||||
void process_request (int j) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < REQUESTS_PER_PROCESS; i++) {
|
||||
if (i == 1 && j == 1) {
|
||||
process_special_request(j);
|
||||
continue;
|
||||
}
|
||||
struct timeval tv;
|
||||
|
||||
Transaction *transaction;
|
||||
transaction = msc_new_transaction(modsec, rules, NULL);
|
||||
|
||||
msc_process_connection(transaction, "127.0.0.1", 12345, "127.0.0.1", 80);
|
||||
msc_process_uri(transaction,
|
||||
"http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3",
|
||||
"GET", "1.1");
|
||||
msc_add_request_header(transaction,
|
||||
(const unsigned char *) "User-Agent",
|
||||
(const unsigned char *) "Basic ModSecurity example");
|
||||
msc_process_request_headers(transaction);
|
||||
msc_process_request_body(transaction);
|
||||
msc_add_response_header(transaction,
|
||||
(const unsigned char *) "Content-type",
|
||||
(const unsigned char *) "text/html");
|
||||
msc_process_response_headers(transaction, 200, "HTTP 1.0");
|
||||
msc_process_response_body(transaction);
|
||||
msc_process_logging(transaction);
|
||||
msc_transaction_cleanup(transaction);
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 500;
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
const char *error = NULL;
|
||||
pid_t pid;
|
||||
int f;
|
||||
|
||||
modsec = msc_init();
|
||||
|
||||
msc_set_connector_info(modsec, "ModSecurity-test v0.0.1-alpha (Simple " \
|
||||
"example on how to use ModSecurity API");
|
||||
|
||||
rules = msc_create_rules_set();
|
||||
|
||||
ret = msc_rules_add_file(rules, main_rule_uri, &error);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Problems loading the rules --\n");
|
||||
fprintf(stderr, "%s\n", error);
|
||||
goto end;
|
||||
}
|
||||
|
||||
msc_rules_dump(rules);
|
||||
|
||||
for (f = 0; f < FORKS; f++) {
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
process_request(f);
|
||||
goto child;
|
||||
}
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 500;
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
wait(NULL);
|
||||
|
||||
child:
|
||||
|
||||
if (pid == 0) {
|
||||
return 0;
|
||||
}
|
||||
end:
|
||||
msc_rules_cleanup(rules);
|
||||
msc_cleanup(modsec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
|
||||
|
||||
noinst_PROGRAMS = simple_request
|
||||
|
||||
simple_request_SOURCES = \
|
||||
simple_request.cc
|
||||
|
||||
simple_request_LDADD = \
|
||||
$(CURL_LDADD) \
|
||||
$(GEOIP_LDADD) \
|
||||
$(GLOBAL_LDADD) \
|
||||
$(LIBXML2_LDADD) \
|
||||
$(LMDB_LDADD) \
|
||||
$(MAXMIND_LDADD) \
|
||||
$(LUA_LDADD) \
|
||||
$(PCRE_LDADD) \
|
||||
$(SSDEEP_LDADD) \
|
||||
$(YAJL_LDADD)
|
||||
|
||||
simple_request_LDFLAGS = \
|
||||
-L$(top_builddir)/src/.libs/ \
|
||||
$(GEOIP_LDFLAGS) \
|
||||
-lmodsecurity \
|
||||
-lpthread \
|
||||
-lm \
|
||||
-lstdc++ \
|
||||
$(LMDB_LDFLAGS) \
|
||||
$(LUA_LDFLAGS) \
|
||||
$(MAXMIND_LDFLAGS) \
|
||||
$(SSDEEP_LDFLAGS) \
|
||||
$(YAJL_LDFLAGS)
|
||||
|
||||
simple_request_CPPFLAGS = \
|
||||
$(GLOBAL_CFLAGS) \
|
||||
-std=c++11 \
|
||||
-I$(top_builddir)/headers \
|
||||
-I$(top_builddir) \
|
||||
-g \
|
||||
-I../others \
|
||||
-fPIC \
|
||||
-O3 \
|
||||
$(CURL_CFLAGS) \
|
||||
$(GEOIP_CFLAGS) \
|
||||
$(GLOBAL_CPPFLAGS) \
|
||||
$(MODSEC_NO_LOGS) \
|
||||
$(YAJL_CFLAGS) \
|
||||
$(LMDB_CFLAGS) \
|
||||
$(LUA_CFLAGS) \
|
||||
$(PCRE_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
SecRule ARGS:param1 "test" "id:1,deny,phase:2,chain,msg:'test'"
|
||||
SecRule ARGS:param1 "test" "log"
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
SecRuleEngine On
|
||||
SecRule ARGS:param1 "test" "id:1,deny"
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue