mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-08-08 01:11:49 +08:00
Bound memory growth in the worker for unauthenticated connections by enforcing HTTP headers limit in addition to HTTP body limit. Resolves: #712 Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
115 lines
3.6 KiB
Bash
Executable File
115 lines
3.6 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Copyright (C) 2026 Nikos Mavrogiannopoulos
|
|
#
|
|
# This file is part of ocserv.
|
|
#
|
|
# ocserv is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by the
|
|
# Free Software Foundation; either version 2 of the License, or (at
|
|
# your option) any later version.
|
|
#
|
|
# ocserv is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with GnuTLS; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
SERV="${SERV:-../src/ocserv}"
|
|
srcdir=${srcdir:-.}
|
|
NO_NEED_ROOT=1
|
|
|
|
. `dirname $0`/common.sh
|
|
|
|
eval "${GETPORT}"
|
|
|
|
echo "Testing HTTP body and header size limits..."
|
|
|
|
update_config test-user-cert.config
|
|
launch_simple_sr_server -d 1 -f -c ${CONFIG}
|
|
PID=$!
|
|
wait_server $PID
|
|
|
|
BODY_LIMIT=$((256 * 1024))
|
|
HDR_LIMIT=$((16 * 1024))
|
|
HDRFILE=test-http-limits.$$.tmp
|
|
CURL_OUT=test-http-limits.$$.curl
|
|
|
|
# Run a POST via socket_wrapper; print HTTP status code to stdout.
|
|
# Returns curl's exit code (28 = timeout, 52 = empty reply, 0 = got response).
|
|
curl_post() {
|
|
LD_PRELOAD=libsocket_wrapper.so \
|
|
curl --silent --insecure --max-time 10 --user-agent "AnyConnect" \
|
|
--write-out "%{http_code}" \
|
|
"$@" -o "$CURL_OUT"
|
|
}
|
|
|
|
echo -n "Testing body within limit (${BODY_LIMIT} bytes)... "
|
|
http_code=$(head -c ${BODY_LIMIT} /dev/zero | \
|
|
curl_post -X POST https://$ADDRESS:$PORT/auth --data-binary @-)
|
|
rc=$?
|
|
if [ $rc -ne 0 ] || [ "$http_code" = "000" ]; then
|
|
echo "FAILED (curl exit=$rc, HTTP=$http_code)"
|
|
cat "$CURL_OUT"
|
|
fail $PID "Body within limit was rejected"
|
|
fi
|
|
echo "ok (HTTP $http_code)"
|
|
|
|
echo -n "Testing body over limit ($((BODY_LIMIT + 1)) bytes)... "
|
|
http_code=$(head -c $((BODY_LIMIT + 1)) /dev/zero | \
|
|
curl_post -X POST https://$ADDRESS:$PORT/auth --data-binary @-)
|
|
rc=$?
|
|
if [ $rc -eq 0 ] && [ "$http_code" != "413" ] && [ "$http_code" != "431" ]; then
|
|
echo "FAILED (curl exit=$rc, HTTP=$http_code)"
|
|
cat "$CURL_OUT"
|
|
fail $PID "Body over limit was not rejected (HTTP $http_code)"
|
|
fi
|
|
echo "ok (HTTP $http_code)"
|
|
|
|
# Generate N headers of 1 KB each into $HDRFILE for curl's -H @file.
|
|
# With a 16 KB limit: 3 headers (3 KB) is within; 20 headers (20 KB) is over.
|
|
HDR_CHUNK=$((1 * 1024))
|
|
gen_headers() {
|
|
n=$1; rm -f "$HDRFILE"; i=0
|
|
while [ $i -lt $n ]; do
|
|
{ printf 'X-Test-%d: ' $i
|
|
head -c ${HDR_CHUNK} /dev/zero | tr '\0' 'A'
|
|
printf '\n'; } >> "$HDRFILE"
|
|
i=$((i+1))
|
|
done
|
|
}
|
|
|
|
echo -n "Testing headers within limit ($((3 * HDR_CHUNK)) bytes)... "
|
|
gen_headers 3
|
|
# Explicit Content-Length: 0 is required: older curl (e.g. 7.76.1 on CentOS 9)
|
|
# omits it for empty bodies, leaving the server unable to determine
|
|
# message_complete and causing a timeout.
|
|
http_code=$(curl_post -X POST -H "Content-Length: 0" -H @"$HDRFILE" \
|
|
https://$ADDRESS:$PORT/auth)
|
|
rc=$?
|
|
if [ $rc -ne 0 ] || [ "$http_code" = "000" ]; then
|
|
echo "FAILED (curl exit=$rc, HTTP=$http_code)"
|
|
cat "$CURL_OUT"
|
|
fail $PID "Headers within limit were rejected"
|
|
fi
|
|
echo "ok (HTTP $http_code)"
|
|
|
|
echo -n "Testing headers over limit ($((20 * HDR_CHUNK)) bytes)... "
|
|
gen_headers 20
|
|
http_code=$(curl_post -X POST -H "Content-Length: 0" -H @"$HDRFILE" \
|
|
https://$ADDRESS:$PORT/auth)
|
|
rc=$?
|
|
if [ $rc -eq 0 ] && [ "$http_code" != "413" ] && [ "$http_code" != "431" ]; then
|
|
echo "FAILED (curl exit=$rc, HTTP=$http_code)"
|
|
cat "$CURL_OUT"
|
|
fail $PID "Headers over limit were not rejected (HTTP $http_code)"
|
|
fi
|
|
echo "ok (HTTP $http_code)"
|
|
|
|
rm -f "$HDRFILE" "$CURL_OUT"
|
|
cleanup
|
|
exit 0
|