OpenBSD lacks support for procfs

Based on
60641282df.

Snapshot of config files are used to ensure that ocserv-sm and
ocserv-worker remain in sync. These snapshots are anonymous files that
are passed via a file descriptor. A worker creates a new file
description and file descriptor by using open(2) on /proc/self/fd.
Unfortunately OpenBSD lacks support for procfs.

Instead of using snapshot of config files let workers use the config
files.

While here add a note to README.md about this limitation, and add a CI
run (from @nmav).

Signed-off-by: Björn Ketelaars <bjorn.ketelaars@hydroxide.nl>
This commit is contained in:
Alan Jowett
2020-06-17 10:36:13 -06:00
committed by Björn Ketelaars
parent baa9ae84db
commit be17dac16f
5 changed files with 69 additions and 12 deletions

View File

@@ -255,6 +255,25 @@ Fedora:
untracked: true
when: always
Fedora-noprocfs:
stage: testing
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- chmod -R o-w tests/data/raddb
- git submodule update --init
- autoreconf -fvi
- ac_cv_file_FILE__proc_self_exe=no ./configure --disable-maintainer-mode --without-docker-tests
- make -j$JOBS
tags:
- shared
- linux
except:
- tags
artifacts:
expire_in: 1 day
untracked: true
when: on_failure
# Tests seccomp filters by asking seccomp to fail with a trap
seccomp/Fedora:
stage: testing

View File

@@ -15,8 +15,13 @@ The program consists of:
# Supported platforms
The OpenConnect VPN server is designed and tested to work, with both IPv6
and IPv4, on Linux systems. It is, however, known to work on FreeBSD, other
BSD derived systems.
and IPv4, on Linux systems. It is, however, known to work on FreeBSD,
OpenBSD and other BSD derived systems.
Known limitation is that on platforms, which do not support procfs(5),
changes to the configuration must only be made while ocserv(8) is stopped.
Not doing so will cause new worker processes picking up the new
configuration while ocserv-main will use the previous configuration.
# Build dependencies

View File

@@ -642,6 +642,8 @@ fi
AM_CONDITIONAL(ENABLE_OIDC_AUTH, test "x$enable_oidc_auth" = xyes)
AM_CONDITIONAL(ENABLE_OIDC_AUTH_TESTS, test "x$enable_oidc_auth" = xyes)
AC_CHECK_FILE(/proc/self/exe, AC_DEFINE([PROC_FS_SUPPORTED],[1], [procfs supported]), [])
uid=$(id -u)
gid=$(id -g)
AC_SUBST([ROOTUID], [$uid])

View File

@@ -1130,6 +1130,7 @@ static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
ctx.reload = (flags&CFG_FLAG_RELOAD)?1:0;
ctx.head = head;
#if defined(PROC_FS_SUPPORTED)
// Worker always reads from snapshot
if ((flags & CFG_FLAG_WORKER) == CFG_FLAG_WORKER) {
char * snapshot_file = NULL;
@@ -1192,6 +1193,27 @@ static void parse_cfg_file(void *pool, const char *file, struct list_head *head,
}
}
#else
const char * cfg_file = file;
if (cfg_file == NULL) {
fprintf(stderr, ERRSTR"no config file!\n");
exit(1);
}
/* parse configuration
*/
ret = ini_parse(cfg_file, cfg_ini_handler, &ctx);
if (ret < 0 && file != NULL && strcmp(file, DEFAULT_CFG_FILE) == 0) {
cfg_file = OLD_DEFAULT_CFG_FILE;
ret = ini_parse(cfg_file, cfg_ini_handler, &ctx);
}
if (ret < 0) {
fprintf(stderr, ERRSTR"cannot load config file %s\n", cfg_file);
exit(1);
}
#endif
/* apply configuration not yet applied.
* We start from the last, which is the default server (firstly

View File

@@ -1015,9 +1015,7 @@ static void listen_watcher_cb (EV_P_ ev_io *w, int revents)
int cmd_fd[2];
pid_t pid;
hmac_component_st hmac_components[3];
char path[_POSIX_PATH_MAX];
char worker_path[_POSIX_PATH_MAX];
size_t path_length;
if (ltmp->sock_type == SOCK_TYPE_TCP || ltmp->sock_type == SOCK_TYPE_UNIX) {
/* connection on TCP port */
@@ -1117,16 +1115,27 @@ static void listen_watcher_cb (EV_P_ ev_io *w, int revents)
safe_memset((uint8_t*)s->hmac_key, 0, sizeof(s->hmac_key));
set_env_from_ws(s);
path_length = readlink("/proc/self/exe", path, sizeof(path)-1);
if (path_length == -1) {
mslog(s, NULL, LOG_ERR, "readlink failed %s", strerror(ret));
exit(1);
}
path[path_length] = '\0';
if (snprintf(worker_path, sizeof(worker_path), "%s-worker", path) >= sizeof(worker_path)) {
mslog(s, NULL, LOG_ERR, "snprint of path %s and ocserv-worker failed", path);
#if defined(PROC_FS_SUPPORTED)
{
char path[_POSIX_PATH_MAX];
size_t path_length;
path_length = readlink("/proc/self/exe", path, sizeof(path)-1);
if (path_length == -1) {
mslog(s, NULL, LOG_ERR, "readlink failed %s", strerror(ret));
exit(1);
}
path[path_length] = '\0';
if (snprintf(worker_path, sizeof(worker_path), "%s-worker", path) >= sizeof(worker_path)) {
mslog(s, NULL, LOG_ERR, "snprint of path %s and ocserv-worker failed", path);
exit(1);
}
}
#else
if (snprintf(worker_path, sizeof(worker_path), "%s-worker", worker_argv[0]) >= sizeof(worker_path)) {
mslog(s, NULL, LOG_ERR, "snprint of path %s and ocserv-worker failed", worker_argv[0]);
exit(1);
}
#endif
worker_argv[0] = worker_path;
execv(worker_path, worker_argv);