#!/bin/bash # # 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 HEAD=$(mktemp) POST=$(mktemp) OUTFILE=$(mktemp) . `dirname $0`/common.sh eval "${GETPORT}" echo "Testing cert-group auto-selection (#692)" # Reproducer for #692: when cert-group-oid is configured and the client # certificate carries exactly one group, and no "select-group" list is # configured (so there is nothing to disambiguate), the server must not # force an extra "select your group" round trip before completing # authentication. function finish { set +e echo " * Cleaning up..." test -n "${CONFIG}" && rm -f ${CONFIG} >/dev/null 2>&1 rm -f $HEAD $POST $OUTFILE >/dev/null 2>&1 cleanup } trap finish EXIT update_config test-group-cert-autoselect.config launch_simple_sr_server -d 1 -f -c ${CONFIG} PID=$! wait_server $PID TARGET=https://$ADDRESS:$PORT cat >$HEAD <<_EOF Accept-Encoding:identity X-Transcend-Version:1 X-Aggregate-Auth:1 Connection:close _EOF echo " * Sanity check: explicit group-select with a single certificate group" # Sanity check: explicitly selecting the (only) certificate group works # and completes authentication immediately. cat >$POST <<_EOF onlygroup _EOF LD_PRELOAD=libsocket_wrapper.so curl -i -A 'OpenConnect VPN Agent v9.12' \ -H @$HEAD -k \ --cert ${srcdir}/certs/user-group-single-cert.pem \ --key ${srcdir}/certs/user-group-key.pem \ -d@$POST $TARGET >$OUTFILE grep 'auth id="success"' $OUTFILE >/dev/null if test $? != 0; then echo "Explicit group selection did not complete authentication" echo "===========================================================" cat $OUTFILE exit 1 fi grep "Set-Cookie: webvpncontext=" $OUTFILE >/dev/null if test $? != 0; then echo "Explicit group selection did not result in a session cookie" echo "=============================================================" cat $OUTFILE exit 1 fi echo " * OK: explicit group selection completed authentication" echo " * Reproducer: single eligible certificate group, no group-select sent" # The actual reproducer: the client certificate has exactly one group # (OU=onlygroup) and the server has no "select-group" list configured # (so the single certificate group is unambiguous). Authenticate without # sending a at all, as a first-contact AnyConnect client # would. Authentication must complete directly, without an extra # "Please select your group" prompt. cat >$POST <<_EOF 4.8.03036 _EOF LD_PRELOAD=libsocket_wrapper.so curl -i -A 'OpenConnect VPN Agent v9.12' \ -H @$HEAD -k \ --cert ${srcdir}/certs/user-group-single-cert.pem \ --key ${srcdir}/certs/user-group-key.pem \ -d@$POST $TARGET >$OUTFILE grep "Please select your group" $OUTFILE >/dev/null if test $? = 0; then echo "Server asked to select a group despite the certificate" echo "containing a single, unambiguous group and no configured" echo "select-group list (issue #692)" echo "==========================================================" cat $OUTFILE exit 1 fi grep 'auth id="success"' $OUTFILE >/dev/null if test $? != 0; then echo "Authentication did not complete with the certificate's" echo "sole group automatically selected" echo "========================================================" cat $OUTFILE exit 1 fi grep "Set-Cookie: webvpncontext=" $OUTFILE >/dev/null if test $? != 0; then echo "Automatic group selection did not result in a session cookie" echo "==============================================================" cat $OUTFILE exit 1 fi echo " * OK: certificate's sole group was auto-selected, no prompt sent" echo " * Ambiguous case: multiple eligible certificate groups, no group-select sent" # Ambiguous case: the client certificate carries multiple groups # (OU=group1, group2, group3, group4) and the server has no # "select-group" list configured, so all of them are eligible and there # is no single unambiguous group to auto-select. The server must still # prompt the client to select a group. cat >$POST <<_EOF 4.8.03036 _EOF LD_PRELOAD=libsocket_wrapper.so curl -i -A 'OpenConnect VPN Agent v9.12' \ -H @$HEAD -k \ --cert ${srcdir}/certs/user-group-cert.pem \ --key ${srcdir}/certs/user-group-key.pem \ -d@$POST $TARGET >$OUTFILE grep "Please select your group" $OUTFILE >/dev/null if test $? != 0; then echo "Server did not ask to select a group despite the certificate" echo "containing multiple, ambiguous groups and no configured" echo "select-group list" echo "==========================================================" cat $OUTFILE exit 1 fi # ocserv always sends a Set-Cookie: webvpncontext= header, even to clear # a non-existing one (webvpncontext=; expires=...1970...). Only a # non-empty cookie value indicates a completed session. grep -E "Set-Cookie: webvpncontext=[^;[:space:]]" $OUTFILE >/dev/null if test $? = 0; then echo "Ambiguous group selection unexpectedly resulted in a session cookie" echo "=====================================================================" cat $OUTFILE exit 1 fi echo " * OK: ambiguous certificate groups still require group selection" # ----------------------------------------------------------------------- # Restart the server with select-group = onlygroup to exercise the inner # filtering loop in auto_select_cert_group(). # ----------------------------------------------------------------------- cleanup mkdir -p $SOCKDIR echo "Testing cert-group auto-selection with select-group filter (#692)" update_config test-group-cert-autoselect-filter.config launch_simple_sr_server -d 1 -f -c ${CONFIG} PID=$! wait_server $PID TARGET=https://$ADDRESS:$PORT echo " * Filtered match: cert group is in select-group list, no group-select sent" # select-group = onlygroup is configured; the client certificate carries # exactly one group (OU=onlygroup) which is in the list. The eligible set # has exactly one entry, so the server must auto-select it and complete # authentication without an extra round trip. cat >$POST <<_EOF 4.8.03036 _EOF LD_PRELOAD=libsocket_wrapper.so curl -i -A 'OpenConnect VPN Agent v9.12' \ -H @$HEAD -k \ --cert ${srcdir}/certs/user-group-single-cert.pem \ --key ${srcdir}/certs/user-group-key.pem \ -d@$POST $TARGET >$OUTFILE grep "Please select your group" $OUTFILE >/dev/null if test $? = 0; then echo "Server prompted for group despite cert's sole group being in" echo "the configured select-group list (select-group filter path)" echo "==========================================================" cat $OUTFILE exit 1 fi grep 'auth id="success"' $OUTFILE >/dev/null if test $? != 0; then echo "Authentication did not complete with cert group auto-selected" echo "from the configured select-group list" echo "==============================================================" cat $OUTFILE exit 1 fi grep "Set-Cookie: webvpncontext=" $OUTFILE >/dev/null if test $? != 0; then echo "Filtered auto-selection did not result in a session cookie" echo "============================================================" cat $OUTFILE exit 1 fi echo " * OK: cert group in select-group list was auto-selected" echo " * Filtered non-match: cert groups not in select-group list, no group-select sent" # select-group = onlygroup is configured; the client certificate carries # four groups (OU=group1..4), none of which match "onlygroup". The eligible # set is empty, so the server must fall back to the group selection prompt. cat >$POST <<_EOF 4.8.03036 _EOF LD_PRELOAD=libsocket_wrapper.so curl -i -A 'OpenConnect VPN Agent v9.12' \ -H @$HEAD -k \ --cert ${srcdir}/certs/user-group-cert.pem \ --key ${srcdir}/certs/user-group-key.pem \ -d@$POST $TARGET >$OUTFILE grep "Please select your group" $OUTFILE >/dev/null if test $? != 0; then echo "Server did not prompt for group despite none of the cert's" echo "groups matching the configured select-group list" echo "==========================================================" cat $OUTFILE exit 1 fi grep -E "Set-Cookie: webvpncontext=[^;[:space:]]" $OUTFILE >/dev/null if test $? = 0; then echo "Non-matching cert groups unexpectedly resulted in a session cookie" echo "===================================================================" cat $OUTFILE exit 1 fi echo " * OK: cert groups not in select-group list still require group selection" exit 0