Regression test for the group-separator=comma option: verifies that
OU= Class attributes with comma-separated group names (as sent by
Freeradius) are correctly parsed when group-separator=comma is set.
Relates: #428
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Freeradius deployments may send groups in the Class attribute using a
comma as separator (e.g. "OU=group1,group2") rather than the semicolon
that ocserv expects by default. Add a group-separator option to the
radius auth configuration to allow this to be changed:
auth = "radius[config=...,group-separator=comma]"
Accepted values are 'semicolon' (default) and 'comma'. The literal
character is not accepted in the config syntax as it conflicts with the
key=value pair delimiter.
Resolves: #428
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Instead of always using a hardcoded $5$fakesalt$ when the requested user
is not found, read_auth_pass() now captures the salt from the first entry
in the passwd file whose password field starts with '$'. This ensures the
crypt() call in plain_auth_pass() uses the same algorithm as real entries,
preventing observable timing differences that could leak username existence.
Falls back to $5$fakesalt$ when no usable entry is found.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
strsep() was used conditionally in plain authentication with fallback
code, whereas radius code used it unconditionally. Rely on strsep()
unconditionally to simplify the code.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Regression test: a user with both a password and OTP configured must not
be able to authenticate by supplying an empty password (even with the
correct OTP).
Relates: #323
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Corrected bugs that prevented a correct password from being accepted after
a wrong one in the same session:
- worker-auth.c: a stale webvpncontext SID cookie caused a reconnecting
client to skip SEC_AUTH_INIT and jump directly to SEC_AUTH_CONT with
a PS_AUTH_FAILED session, which sec-mod rejects.
- auth/plain.c: the 'failed' flag was sticky across retry attempts, so a
correct password following a wrong one was still treated as failure.
Refactored into 'unknown_user' (sticky, for timing protection) and a
local 'wrong_pass' (fresh each call). crypt() is now always called
regardless of whether the user exists to normalise response timing and
prevent username enumeration.
Resolves: #323
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Several tests run longer without taking any resources, allow
more parallelization to finish faster.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Ensure the client is killed eventually to prevent an openconnect
re-connect to keep the test up.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This deprecates Ubuntu 20.04 builds and Fedora 42 builds
and tests the latest version.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This validates that restrict-user-to-ports and
restrict-user-to-routes are enforced by the fw script.
The test verifies three cases after connecting with a config that
allows only TCP 80 and advertises a single route:
- allowed port + advertised route: connection succeeds
- denied port + advertised route: rejected at port level
- allowed port + non-advertised route: rejected at route level
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
The has_more flag passed to print_end_block() used the raw array index,
producing a trailing comma when the last entry in args->cookies[] was
filtered out (e.g. a PS_AUTH_FAILED session lingering until cookie-timeout).
Fix by adding a pre-pass that collects the indices of entries that will
actually be printed into a C99 variable array vis[].
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Add a worker_exit() wrapper that calls __gcov_exit() before _exit()
when built with coverage instrumentation (-Db_coverage=true -> WITH_COVERAGE).
As atexit() handlers from libgcov are not triggered by SIGTERM, it caused
caused all worker-side coverage data to be silently lost.
umask(022) is set before __gcov_exit() so the .gcda files
are written with 0644 permissions and are readable by lcov.
This restores coverage for code paths that run exclusively in the
worker, such as lzs_compress(), lz4_compress().
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This tests: show status, reload, show iroutes, disconnect id,
show sessions, show ip ban points.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
The sleep-connect-script blocked on both connect and disconnect invocations.
When the server shuts down, two disconnect scripts race past the test -f
check simultaneously and both sleep 600s, exceeding the test timeout.
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
Add 'terminate user', 'terminate id' and 'terminate session' commands
to occtl that disconnect users and invalidate their session cookies,
preventing reconnection with cached credentials.
Short session IDs are resolved to full safe_id by fetching the cookie
list from sec-mod via CTL_CMD_LIST_COOKIES with prefix matching and
ambiguity detection. Active sessions trigger a warning before
invalidation.
Add integration tests for all three terminate commands.
Signed-off-by: Ivan Verbin <verbinivan@gmail.com>
Fix PID-based namespace name collisions by:
- Extracting last 9 digits of PID (instead of first 4)
- Shortening interface names to fit 15-character IFNAMSIZ limit
Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>