Commit Graph
625 Commits
Author SHA1 Message Date
Nikos Mavrogiannopoulos d3372cbcb4 worker: drain TUN in a burst loop to avoid per-packet epoll_wait()
Previously tun_watcher_cb() called tun_mainloop() exactly once per
libev wakeup and then returned, causing ev_run() to call epoll_wait()
again before the next packet.  At high packet rates the TUN device
stays continuously readable, so this wastes one epoll_wait() syscall
per packet (~20-30 µs each in the report) and keeps the worker nearly
idle while the TUN queue grows.  The result is severe packet loss on the
TUN→client path (74% loss reported at 900 Mbps in issue #423).

Fix by looping in tun_watcher_cb() up to TUN_BURST_MAX iterations before
yielding back to the event loop and making the tun fd non-blocking. That
resulted to a reorganization of tls_mainloop() / dtls_mainloop() via
parse_data() to queue packet when the tunfd isn't writeable.

Resolves: #423

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-30 22:49:07 +02:00
Dimitri Papadopoulos 4b216473d5 Fix calculation of avg_auth_time across sec-mod instances
Resolves: #736

Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-05-24 11:47:26 +02:00
Nikos Mavrogiannopoulos efd41d300f Merge branch 'tmp-711' into 'master'
Set `sa` before attempting to set `sa->sin6_family`

Closes #711

See merge request openconnect/ocserv!554
2026-05-24 09:22:08 +00:00
Nikos Mavrogiannopoulos ae021ecf58 Merge branch 'anyconnect-bye-packet' into 'master'
Handle AnyConnect BYE packet with reconnect intention (0x91)

Closes #732

See merge request openconnect/ocserv!555
2026-05-23 14:25:22 +00:00
Grigory Trenin 2ff4154159 Distinguish reason codes in AnyConnect BYE packets
Cisco AnyConnect clients may send a BYE packet with a 0x91 payload,
followed by ASCII text "Reconnecting the VPN tunnel."

Resolves: #732

Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-05-23 08:36:18 -04:00
Nikos Mavrogiannopoulos e5894dba7d NEWS: doc update
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-23 07:43:46 +02:00
Nikos Mavrogiannopoulos bb9bcd7461 main: remove cgroup support in favour of systemd resource controls
Native cgroup placement is removed. Delegating resource enforcement
to systemd eliminates the privileged /sys/fs/cgroup writes from
the main process and simplifies the code.

Administrators who previously relied on the 'cgroup' option should use
the [Service] section of the ocserv unit file instead; see
systemd.resource-control(5) for details.

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-23 07:09:23 +02:00
Nikos Mavrogiannopoulos 25861ab602 Merge branch 'tmp-nettle4' into 'master'
Build against GNU Nettle 4

Closes #697

See merge request openconnect/ocserv!553
2026-05-21 06:35:54 +00:00
Nikos Mavrogiannopoulos 788b1a2b30 Merge branch 'tmp-fix-716' into 'master'
worker: stop HTTP parser at message boundary to prevent request pipelining confusion

Closes #716

See merge request openconnect/ocserv!549
2026-05-21 06:34:06 +00:00
Dimitri Papadopoulos 550e9327cc Set sa before attempting to set sa->sin6_family
Fixes #711.

Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-05-19 23:22:34 +02:00
Dimitri Papadopoulos b97aa4d97f Build against GNU Nettle 4
Fixes #697. Follow-up of !535 / 82572986.

Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-05-19 21:23:03 +02:00
Nikos Mavrogiannopoulos e567f92e64 Removed unnecessary CA and certificate handlers
This removes certificate and CA handlers not used by the openconnect
client. This is a hardening measure to further reduce the attack surface
of the worker process.

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-19 20:11:33 +02:00
Dimitri Papadopoulos 825729868e Build against GNU Nettle 4
From the NEWS file:
https://git.lysator.liu.se/nettle/nettle/-/blob/master/NEWS

	Interface changes:

	* The _digest functions for hash algorithms, MACs and AEADs no
	  longer take the desired digest size as argument, instead,
	  they always produce the full-size digest. The typedef
	  nettle_hash_digest_func has also been changed accordingly.

Fixes #697.

Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-05-17 13:13:39 +02:00
Nikos Mavrogiannopoulos 01f2787ab6 worker: reject HTTP pipelining to prevent request confusion
When two HTTP requests arrived in the same TLS read buffer, a single
llhttp_execute() call would fire callbacks for both requests inline.
Because http_req_reset() is not called between them, ws->req ended up
reflecting the second request's URL and headers, silently discarding
the first.  In the worst case, body bytes from the first request
accumulated alongside the second request's body.

Fix this by registering an on_message_begin callback that returns
HPE_PAUSED when an existing message is detected.

Resolves: #716

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-15 06:42:24 +02:00
Grigory Trenin 61f013ae3a pam: add 'service' sub-option to auth directive
This allows users to specify a custom PAM service name, enabling
per-virtual-host PAM stacks.For example:
auth = "pam[service=vpn1,gid-min=1000]"

Resolves: #718

Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-05-08 21:00:07 -04:00
Dimitri Papadopoulos eb886a7c67 Include <sys:socket.h> for AF_INET
Required to build on FreeBSD 15.

Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-05-06 20:33:03 +02:00
Nikos Mavrogiannopoulos 22bbad4eb5 worker: add per-worker memory limit via RLIMIT_DATA
Introduce a per-worker heap cap as defense-in-depth against
memory-exhaustion DoS attacks. The limit uses RLIMIT_DATA rather
than RLIMIT_AS: since Linux 4.7 RLIMIT_DATA covers brk and private
anonymous mmap regions, i.e, the paths used by malloc and talloc, while
ignoring shared-library file mappings that inflate RLIMIT_AS without
reflecting actual allocation.

This aligns with haproxy's handling. See also:
https://github.com/torvalds/linux/commit/84638335900f1995495838fe1bd4870c43ec1f67
https://sources.debian.org/src/haproxy/3.2.17-1/src/limits.c?hl=486#L486
https://www.kernel.org/doc/html/latest/mm/overcommit-accounting.html

The cap is computed at worker startup by reading the data+stack field
from /proc/self/statm.

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-06 13:54:40 +02:00
Nikos Mavrogiannopoulos 9c44e09356 ocserv-fw-nftables: replace ipcalc with pure-shell mask_to_prefix
ipcalc was used only to convert dotted-decimal subnet masks to CIDR
prefix lengths (e.g. 255.255.0.0 -> 16), replaced with a POSIX shell
script.

Relates: #709

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-02 17:21:38 +02:00
Nikos Mavrogiannopoulos e7d79e232d radius-auth: fix Framed-IPv6-Prefix routes being silently dropped
When processing a RADIUS Access-Accept with Framed-IPv6-Prefix, the code
passed the wrong value for it. Corrected by passing the actual prefix.

Fixes: #710

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-05-01 16:31:38 +02:00
Grigory Trenin a79e2f1cd5 Respect tunnel-all-dns in per-user/group config
Ensure that 'tunnel-all-dns' setting is honoured when overridden
in user or group-specific configuration files.

Resolves: #708

Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-04-26 21:05:06 -04:00
Nikos Mavrogiannopoulos 139ff827d9 config: restructure per-vhost configuration for clarity and maintainability
Introduce a protobuf-generated ReloadableConfig (cfg.proto) to hold all
fields that reload on SIGHUP, and separate them from static_cfg_st, which
holds fields that require a server restart.  Named vhosts inherit from the
default vhost via a pack/unpack round-trip. Adding a new config field
only requires editing cfg.proto.  Struct and accessor names (ReloadableConfig,
static_cfg_st, GETRCONFIG, GETSCONFIG) now reflect each field's lifetime.
A new unit test covers the full inheritance path.

Resolves: #705

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-22 20:29:15 +02:00
Grigory Trenin eddd29f59b Do not forward UDP until client is authenticated
Do not forward DTLS packets until the client is authenticated to
prevent the race between AUTH_COOKIE_REP and CMD_UDP_FD messages
on the command socket.

Closes #706

Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-04-21 07:06:59 -04:00
Nikos Mavrogiannopoulos da90b76b07 bumped versions
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-17 00:08:27 +02:00
Nikos Mavrogiannopoulos c520accb84 Released 1.4.2
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-16 23:27:59 +02:00
Nikos Mavrogiannopoulos 5d0a4dadc4 NEWS: documented updates
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-16 22:53:37 +02:00
Nikos Mavrogiannopoulos d3eceef085 Merge branch '64bit-timestamps' into 'master'
protobuf: use 64-bit signed integers for timestamp fields

See merge request openconnect/ocserv!506
2026-04-14 19:03:05 +00:00
Grigory Trenin cde58c22be protobuf: use 64-bit signed integers for timestamp fields
Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-04-14 13:59:05 -04:00
Grigory Trenin db125634b8 Allow using no-udp option in vhosts
Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-04-14 13:26:32 -04:00
Nikos Mavrogiannopoulos 4a0a087996 config: align default values with sample.config
Several options had hardcoded or named defaults in apply_default_conf()
that diverged from the values documented in doc/sample.config, leading
to silent behaviour differences for servers running without explicit
configuration.

Relates: #680

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-14 18:57:45 +02:00
Nikos Mavrogiannopoulos 611eb00527 config: add scope annotations and validation script
Add machine-readable [scope: X] annotations to doc/sample.config and
src/vpn.h struct fields to document which config options are permanent,
global-only, per-vhost, or per-user/group overridable.

Scope vocabulary:
  global (non-reloadable)  -- in perm_cfg_st; requires restart; cannot differ per vhost
  vhost (non-reloadable)   -- in perm_cfg_st; requires restart; can differ per vhost
  global            -- in cfg_st; reloadable; cannot be set in [vhost:] sections
  vhost             -- in cfg_st; reloadable; can differ per vhost
  vhost user        -- in cfg_st; reloadable; also overridable per user/group

Add tests/check-config-scope.py: a script that cross-checks the annotations
against the actual code:
  (a) every option in sample.config has a [scope:] annotation
  (b-c) [global] options match error_on_vhost() calls in config.c
  (d-e) [vhost user] options match handlers in src/sup-config/file.c
  (f) every field in cfg_st and perm_cfg_st has a [scope:] comment

Also fix a pre-existing bug in src/sup-config/file.c: the tunnel-all-dns
option was compared using an underscore ("tunnel_all_dns") instead of
the correct dash ("tunnel-all-dns"), silently ignoring the per-user
setting.

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-14 18:57:45 +02:00
Nikos Mavrogiannopoulos 62a5f72864 DPD time: corrected duplicate assignment and set value for mobile-dpd
Resolves: #680

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-04-14 18:57:45 +02:00
Nikos Mavrogiannopoulos db50c02cbd Merge branch 'tmp-radius-group-separator' into 'master'
radius: add group-separator option for OU= Class attributes

Closes #428

See merge request openconnect/ocserv!513
2026-04-10 04:29:39 +00:00
Grigory Trenin bf12b9fe9c Fix global option inheritance for virtual hosts
Ensure global options are properly copied to virtual hosts when not
explicitly specified.

This change also:
- Documents global options that cannot be overridden in virtual hosts.
- Adds a 'VIRTUAL HOSTS' section to the man page to clarify behavior.

Closes #698

Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-04-09 20:20:45 -04:00
Nikos Mavrogiannopoulos 828fca691e radius: add group-separator option for OU= Class attributes
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>
2026-04-06 21:27:28 +02:00
Nikos Mavrogiannopoulos ebb34f6787 auth/plain: fix password retry and prevent username enumeration via timing
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>
2026-04-03 13:55:07 +02:00
Nikos Mavrogiannopoulos 598bcf405e Added ocserv-fw for nftables
This also introduces a basic functional test for ocserv-fw.

Resolves: #397

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-03-29 16:55:12 +02:00
Nikos Mavrogiannopoulos 18401eb298 Replaced autoconf with meson build files
Resolves: #699

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-03-20 20:47:27 +01:00
Ivan Verbin a8730a6997 occtl: add terminate commands for session cookie invalidation
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>
2026-03-15 17:05:29 +03:00
Dimitri PapadopoulosandNikos Mavrogiannopoulos a309ecead0 llhttp: updated to latest version 9.3.1
Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-03-02 08:19:50 +01:00
Nikos Mavrogiannopoulos 1cb1e5706f NEWS: clarified fix on authentication bypass
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-03-02 08:13:54 +01:00
Nikos Mavrogiannopoulos 38458a8305 prepare for 1.4.2
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-03-01 19:19:06 +01:00
Nikos Mavrogiannopoulos 7477c32ba5 NEWS: updated
Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
2026-02-28 11:47:15 +01:00
Dimitri Papadopoulos 32979e6519 updated to protobuf 1.5.2
Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-01-30 00:55:46 +01:00
Dimitri Papadopoulos Orfanos ba19dcd3be Merge branch 'tmp-NEWS' into 'master'
Fix NEWS file

See merge request openconnect/ocserv!501
2026-01-30 01:53:08 +02:00
Nikos Mavrogiannopoulos e05485f008 Merge branch 'issue599' into 'master'
Fix session timeout bypass

Closes #599

See merge request openconnect/ocserv!489
2026-01-29 18:47:55 +00:00
Dimitri Papadopoulos Orfanos 360e4714e3 Merge branch 'bugfix/ban-json' into 'master'
occtl: Fix 'show ip bans' may produce invalid JSON (#683)

Closes #683

See merge request openconnect/ocserv!495
2026-01-26 09:16:47 +02:00
Dimitri Papadopoulos 842bccc283 Fix NEWS file
Signed-off-by: Dimitri Papadopoulos <3350651-DimitriPapadopoulos@users.noreply.gitlab.com>
2026-01-26 08:15:23 +01:00
Grigory Trenin fb41d4203d Fix session timeout bypass
- Fixes an issue #599 where the session timeout could be bypassed
  by reconnecting, such as through a laptop lid close/open cycle.
- Adds 'Session started at:' field to 'occtl show user' output.

Signed-off-by: Grigory Trenin <grigory.trenin@gmail.com>
2026-01-25 18:59:13 -05:00
Nikos Mavrogiannopoulos 882759092c Merge branch 'tmp-udp_port' into 'master'
Initialise udp_port using vhost config section

Closes #612

See merge request openconnect/ocserv!431
2026-01-25 17:30:35 +00:00
Nikos Mavrogiannopoulos d06e67d102 Merge branch 'tmp-inih' into 'master'
inih: updated to latest version r62

See merge request openconnect/ocserv!437
2026-01-25 17:01:47 +00:00