From 0aee9ca7e76887fb5752c15ef63bfb7a356df06e Mon Sep 17 00:00:00 2001 From: james Date: Mon, 21 Jan 2008 19:34:13 +0000 Subject: Allow OpenVPN to run completely unprivileged under Linux by allowing openvpn --mktun to be used with --user and --group to set the UID/GID of the tun device node. Also added --iproute option to allow an alternative command to be executed in place of the default iproute2 command (Alon Bar-Lev). git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2639 e7ae566f-a301-0410-adde-c780ea21d3b5 --- tun.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'tun.c') diff --git a/tun.c b/tun.c index 8c8616a..3a740bf 100644 --- a/tun.c +++ b/tun.c @@ -577,7 +577,8 @@ do_ifconfig (struct tuntap *tt, * Set the MTU for the device */ openvpn_snprintf (command_line, sizeof (command_line), - IPROUTE_PATH " link set dev %s up mtu %d", + "%s link set dev %s up mtu %d", + iproute_path, actual, tun_mtu ); @@ -590,7 +591,8 @@ do_ifconfig (struct tuntap *tt, * Set the address for the device */ openvpn_snprintf (command_line, sizeof (command_line), - IPROUTE_PATH " addr add dev %s local %s peer %s", + "%s addr add dev %s local %s peer %s", + iproute_path, actual, ifconfig_local, ifconfig_remote_netmask @@ -599,7 +601,8 @@ do_ifconfig (struct tuntap *tt, system_check (command_line, es, S_FATAL, "Linux ip addr add failed"); } else { openvpn_snprintf (command_line, sizeof (command_line), - IPROUTE_PATH " addr add dev %s %s/%d broadcast %s", + "%s addr add dev %s %s/%d broadcast %s", + iproute_path, actual, ifconfig_local, count_netmask_bits(ifconfig_remote_netmask), @@ -1162,8 +1165,20 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 #ifdef TUNSETPERSIST +/* + * This can be removed in future + * when all systems will use newer + * linux-headers + */ +#ifndef TUNSETOWNER +#define TUNSETOWNER _IOW('T', 204, int) +#endif +#ifndef TUNSETGROUP +#define TUNSETGROUP _IOW('T', 206, int) +#endif + void -tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const struct tuntap_options *options) +tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options) { struct tuntap *tt; @@ -1174,6 +1189,26 @@ tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, open_tun (dev, dev_type, dev_node, ipv6, tt); if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0) msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); + if (username != NULL) + { + struct user_state user_state; + + if (!get_user (username, &user_state)) + msg (M_ERR, "Cannot get user entry for %s", username); + else + if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0) + msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev); + } + if (groupname != NULL) + { + struct group_state group_state; + + if (!get_group (groupname, &group_state)) + msg (M_ERR, "Cannot get group entry for %s", groupname); + else + if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0) + msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev); + } close_tun (tt); msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF")); } @@ -1185,6 +1220,19 @@ close_tun (struct tuntap *tt) { if (tt) { +#ifdef CONFIG_FEATURE_IPROUTE + char command_line[256]; + /* + * Flush IP configuration for the device + */ + openvpn_snprintf (command_line, sizeof (command_line), + "%s addr flush dev %s", + iproute_path, + tt->actual_name + ); + msg (M_INFO, "%s", command_line); + system_check (command_line, NULL, S_FATAL, "Linux ip flush failed"); +#endif close_tun_generic (tt); free (tt); } -- cgit