From 1d27f9d7bca6ee7cf4005ac4ab03b6bea8bdc2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Lab=C3=A1th?= Date: Thu, 22 Sep 2022 15:57:45 +0200 Subject: [PATCH] add option to permit running as non-root On a configured system, running as a non-privileged user is possible. Keep bailing out when running as non-root for those who have not configured their systems, but add an option to permit it for those who have configured their systems. In particular, one would need permission to run pppd (or equivalent), and setup ppp such that it handles ip, route, dns configuration. cat > /etc/ppp/peers/myconnection << 'EOF' 38400 :192.0.2.1 noipdefault noaccomp noauth default-asyncmap nopcomp receive-all nodefaultroute nodetach lcp-max-configure 40 mru 1354 ipparam myconnection EOF cat > /etc/ppp/ip-up.local << 'EOF' case "$PPP_IPPARAM" in myconnection) # setup networking, dns, etc - run via ppp as root ip route add 1.2.3.4/24 dev "$PPP_IFACE" ;; esac 2>&1 | logger -p daemon.debug -i -t "$0" true EOF chmod a+x /etc/ppp/ip-up.local for f in ip-down ipv6-down ipv6-up; do script="/etc/ppp/${f}.local" echo '#!/bin/sh' > "$script" chmod a+x "$script" done Then one could start the tunnel, unprivileged with a config like cat > ~/zssk.conf << 'EOFCONF' host = 1.2.3.4 port = 443 username = myuser password = mypass trusted-cert = 1234567890123456789345678456789034567890456789034567891234567890 set-routes = 0 set-dns = 0 pppd-call = myconnection allow-nonroot = 1 EOFCONF --- src/config.c | 12 ++++++++++++ src/config.h | 1 + src/main.c | 8 ++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index 9c6d3c5d..671d7660 100644 --- a/src/config.c +++ b/src/config.c @@ -62,6 +62,7 @@ const struct vpn_config invalid_cfg = { .use_syslog = -1, .half_internet_routes = -1, .persistent = -1, + .allow_nonroot = -1, #if HAVE_USR_SBIN_PPPD .pppd_log = NULL, .pppd_plugin = NULL, @@ -331,6 +332,15 @@ int load_config(struct vpn_config *cfg, const char *filename) continue; } cfg->persistent = persistent; + } else if (strcmp(key, "allow-nonroot") == 0) { + int allow_nonroot = strtob(val); + + if (allow_nonroot < 0) { + log_warn("Bad allow-nonroot in configuration file: \"%s\".\n", + val); + continue; + } + cfg->allow_nonroot = allow_nonroot; #if HAVE_USR_SBIN_PPPD } else if (strcmp(key, "pppd-use-peerdns") == 0) { int pppd_use_peerdns = strtob(val); @@ -560,6 +570,8 @@ void merge_config(struct vpn_config *dst, struct vpn_config *src) dst->half_internet_routes = src->half_internet_routes; if (src->persistent != invalid_cfg.persistent) dst->persistent = src->persistent; + if (src->allow_nonroot != invalid_cfg.allow_nonroot) + dst->allow_nonroot = src->allow_nonroot; #if HAVE_USR_SBIN_PPPD if (src->pppd_log) { free(dst->pppd_log); diff --git a/src/config.h b/src/config.h index eaf7f825..2f21084a 100644 --- a/src/config.h +++ b/src/config.h @@ -109,6 +109,7 @@ struct vpn_config { int half_internet_routes; unsigned int persistent; + int allow_nonroot; #if HAVE_USR_SBIN_PPPD char *pppd_log; diff --git a/src/main.c b/src/main.c index c1fba334..a5bf1804 100644 --- a/src/main.c +++ b/src/main.c @@ -166,6 +166,8 @@ PPPD_USAGE \ " --seclevel-1 If --cipher-list is not specified, add @SECLEVEL=1 to\n" \ " (compiled in) list of ciphers. This lowers limits on\n" \ " dh key." help_seclevel_1 "\n" \ +" --allow-nonroot Permit running without root privileges.\n" \ +" Requires system/ppp configuration.\n" \ " --persistent= Run the vpn persistently in a loop and try to re-\n" \ " connect every seconds when dropping out.\n" \ " -v Increase verbosity. Can be used multiple times\n" \ @@ -238,6 +240,7 @@ int main(int argc, char *argv[]) .use_syslog = 0, .half_internet_routes = 0, .persistent = 0, + .allow_nonroot = 0, #if HAVE_RESOLVCONF .use_resolvconf = USE_RESOLVCONF, #endif @@ -308,6 +311,7 @@ int main(int argc, char *argv[]) {"cipher-list", required_argument, NULL, 0}, {"min-tls", required_argument, NULL, 0}, {"seclevel-1", no_argument, &cli_cfg.seclevel_1, 1}, + {"allow-nonroot", no_argument, &cli_cfg.allow_nonroot, 1}, #if HAVE_USR_SBIN_PPPD {"pppd-use-peerdns", required_argument, NULL, 0}, {"pppd-no-peerdns", no_argument, &cli_cfg.pppd_use_peerdns, 0}, @@ -732,8 +736,8 @@ int main(int argc, char *argv[]) if (cfg.otp[0] != '\0') log_debug("One-time password = \"%s\"\n", cfg.otp); - if (geteuid() != 0) { - log_error("This process was not spawned with root privileges, which are required.\n"); + if (!cfg.allow_nonroot && (geteuid() != 0)) { + log_error("This process was not spawned with root privileges, which are normally required. If your system is configured, use --allow-nonroot.\n"); ret = EXIT_FAILURE; goto exit; }