From 4798c7d95bf4c597e9457d954b5da90a017e2738 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 8c6f0a16..4c481706 100644 --- a/src/config.c +++ b/src/config.c @@ -61,6 +61,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, @@ -325,6 +326,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); @@ -552,6 +562,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 445d89c3..a35cb025 100644 --- a/src/config.h +++ b/src/config.h @@ -108,6 +108,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 325d50eb..21269f11 100644 --- a/src/main.c +++ b/src/main.c @@ -164,6 +164,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" \ @@ -235,6 +237,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 @@ -304,6 +307,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}, @@ -722,8 +726,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; }