aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn/dco.c
diff options
context:
space:
mode:
authorTimo Rothenpieler2022-08-17 15:18:17 +0200
committerGert Doering2022-08-17 16:08:07 +0200
commitda31c1654c8534658157cfe9c9de5750ee752608 (patch)
treed58bdfc32a1d68d04f30ec03dfefca86636ae2f5 /src/openvpn/dco.c
parent9b17fed14bc534353d9a5e2d90d902bb093df3c2 (diff)
downloadopenvpn-da31c1654c8534658157cfe9c9de5750ee752608.zip
openvpn-da31c1654c8534658157cfe9c9de5750ee752608.tar.gz
dco: disable DCO if --user specified but unable to retain capabilities
If run under network manager, OpenVPN starts with uid=0 and '--user nm-openvpn', but is lacking the CAP_SETPCAP capabilities to retain CAP_NET_ADMIN after dropping root privileges. In DCO mode, OpenVPN must have CAP_NET_ADMIN today, always, otherwise TLS renegotiation / key rotation will not be possible. So, check at startup, if --user is specified, if CAP_NET_ADMIN is permitted and CAP_SETPCAP is available. If either of the capabilities is missing, disable DCO. Traditional tun/tap works with "uid=0 on tun open, and setuid() afterwards". Long-Term, get NM to enable OpenVPN to run with CAP_NET_ADMIN. Debian bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1017379 Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org> Tested-By: Bernhard Schmidt <berni@birkenwald.de> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <20220817131817.467-1-timo@rothenpieler.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24952.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/dco.c')
-rw-r--r--src/openvpn/dco.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index caa4ce3..b7db23f 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -44,6 +44,10 @@
#include "ssl_ncp.h"
#include "tun.h"
+#ifdef HAVE_LIBCAPNG
+#include <cap-ng.h>
+#endif
+
static int
dco_install_key(struct tls_multi *multi, struct key_state *ks,
const uint8_t *encrypt_key, const uint8_t *encrypt_iv,
@@ -247,6 +251,28 @@ dco_check_option_conflict_platform(int msglevel, const struct options *o)
}
}
#endif /* if defined(TARGET_LINUX) */
+
+#if defined(HAVE_LIBCAPNG)
+ /* DCO can't operate without CAP_NET_ADMIN. To retain it when switching user
+ * we need CAP_SETPCAP. CAP_NET_ADMIN also needs to be part of the permitted set
+ * of capabilities in order to retain it.
+ */
+ if (o->username)
+ {
+ if (!capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP))
+ {
+ msg(msglevel, "--user specified but lacking CAP_SETPCAP. "
+ "Cannot retain CAP_NET_ADMIN. Disabling data channel offload");
+ return false;
+ }
+ if (!capng_have_capability(CAPNG_PERMITTED, CAP_NET_ADMIN))
+ {
+ msg(msglevel, "--user specified but not permitted to retain CAP_NET_ADMIN. "
+ "Disabling data channel offload");
+ return false;
+ }
+ }
+#endif /* if defined(HAVE_LIBCAPNG) */
return true;
}