mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-08-09 09:51:49 +08:00
ocserv: exit with error code on error
Relates: #615 Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
+2
-1
@@ -904,6 +904,7 @@ static void sec_mod_child_watcher_cb(struct ev_loop *loop, ev_child *w,
|
||||
|
||||
ev_child_stop(loop, w);
|
||||
mslog(s, NULL, LOG_ERR, "ocserv-secmod died unexpectedly");
|
||||
s->abnormal_exit = 1;
|
||||
ev_feed_signal_event(loop, SIGTERM);
|
||||
}
|
||||
|
||||
@@ -1815,7 +1816,7 @@ int main(int argc, char *argv[])
|
||||
talloc_free(s->main_pool);
|
||||
closelog();
|
||||
|
||||
return 0;
|
||||
return s->abnormal_exit ? EXIT_FAILURE : 0;
|
||||
}
|
||||
|
||||
extern char **pam_auth_group_list;
|
||||
|
||||
@@ -317,6 +317,8 @@ typedef struct main_server_st {
|
||||
|
||||
struct if_address_st *if_addresses;
|
||||
unsigned int if_addresses_count;
|
||||
|
||||
unsigned int abnormal_exit; /* set on unexpected child death */
|
||||
} main_server_st;
|
||||
|
||||
void clear_lists(main_server_st *s);
|
||||
|
||||
@@ -126,6 +126,7 @@ if have_cwrap
|
||||
'drain-server', 'drain-server-fail',
|
||||
'test-ignore-querystring-of-post',
|
||||
'test-group-cert', 'test-fork', 'test-pass-svc', 'test-cert-svc',
|
||||
'test-secmod-kill',
|
||||
]
|
||||
|
||||
if have_cwrap_all
|
||||
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
#!/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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Regression test for https://gitlab.com/openconnect/ocserv/-/work_items/615:
|
||||
# when sec-mod dies unexpectedly, ocserv must exit with a non-zero exit code.
|
||||
|
||||
SERV="${SERV:-../src/ocserv}"
|
||||
srcdir=${srcdir:-.}
|
||||
NO_NEED_ROOT=1
|
||||
PIDFILE=ocserv-pid.$$.tmp
|
||||
|
||||
. "$(dirname "$0")/common.sh"
|
||||
|
||||
eval "${GETPORT}"
|
||||
|
||||
echo "Testing that ocserv exits with a non-zero code when sec-mod is killed..."
|
||||
|
||||
update_config test1.config
|
||||
launch_simple_sr_server -d 1 -p "${PIDFILE}" -f -c "${CONFIG}"
|
||||
BGPID=$!
|
||||
|
||||
sleep 3
|
||||
|
||||
echo "Background job PID (shell): ${BGPID}"
|
||||
|
||||
if ! test -f "${PIDFILE}"; then
|
||||
echo "Server did not start (no PID file after 3s)"
|
||||
kill "${BGPID}" 2>/dev/null
|
||||
wait "${BGPID}" 2>/dev/null
|
||||
rm -f "${CONFIG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PID=$(cat "${PIDFILE}")
|
||||
echo "PID from file: ${PID}"
|
||||
|
||||
if test -z "${PID}"; then
|
||||
echo "PID file is empty"
|
||||
kill "${BGPID}" 2>/dev/null
|
||||
wait "${BGPID}" 2>/dev/null
|
||||
rm -f "${PIDFILE}" "${CONFIG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "${PID}" != "${BGPID}"; then
|
||||
echo "Note: PIDFILE PID (${PID}) differs from background job PID (${BGPID})"
|
||||
fi
|
||||
|
||||
echo "Server started with PID ${PID}"
|
||||
|
||||
# Locate the sec-mod child. Try pgrep -P first (procps), then fall back
|
||||
# to a /proc scan for portability (BusyBox, Alpine, etc.).
|
||||
echo "Looking for children of PID ${PID}:"
|
||||
|
||||
SECMOD_PID=$(pgrep -P "${PID}" 2>/dev/null | head -1)
|
||||
echo " pgrep -P ${PID}: '${SECMOD_PID}'"
|
||||
|
||||
if test -z "${SECMOD_PID}"; then
|
||||
echo " pgrep failed or unavailable; scanning /proc..."
|
||||
for f in /proc/[0-9]*/status; do
|
||||
ppid=$(sed -n 's/^PPid:[[:space:]]*//p' "$f" 2>/dev/null)
|
||||
if test "$ppid" = "$PID"; then
|
||||
SECMOD_PID="${f%/status}"
|
||||
SECMOD_PID="${SECMOD_PID##*/proc/}"
|
||||
echo " found child via /proc: ${SECMOD_PID}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "${SECMOD_PID}"; then
|
||||
echo "Could not find sec-mod child of PID ${PID}"
|
||||
echo "All processes (ps):"
|
||||
ps -e -o pid= -o ppid= -o comm= 2>/dev/null || ps 2>/dev/null || true
|
||||
kill "${BGPID}" 2>/dev/null
|
||||
wait "${BGPID}" 2>/dev/null
|
||||
rm -f "${PIDFILE}" "${CONFIG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Killing sec-mod (PID ${SECMOD_PID})..."
|
||||
kill -9 "${SECMOD_PID}"
|
||||
|
||||
# Main detects the death via ev_child, sets abnormal_exit, and calls
|
||||
# terminate_server. Use BGPID (our direct child) so that wait is reliable.
|
||||
wait "${BGPID}"
|
||||
EXITCODE=$?
|
||||
|
||||
echo "ocserv (PID ${BGPID}) exited with code ${EXITCODE}"
|
||||
|
||||
rm -f "${PIDFILE}" "${CONFIG}"
|
||||
|
||||
if test "${EXITCODE}" = "0"; then
|
||||
echo "FAIL: ocserv exited with code 0, expected non-zero"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK: ocserv exited with code ${EXITCODE}"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user