#!/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