git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2639 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -426,7 +426,7 @@ do_persist_tuntap (const struct options *options) |
| 426 | 426 |
"options --mktun or --rmtun should only be used together with --dev"); |
| 427 | 427 |
tuncfg (options->dev, options->dev_type, options->dev_node, |
| 428 | 428 |
options->tun_ipv6, options->persist_mode, |
| 429 |
- &options->tuntap_options); |
|
| 429 |
+ options->username, options->groupname, &options->tuntap_options); |
|
| 430 | 430 |
if (options->persist_mode && options->lladdr) |
| 431 | 431 |
set_lladdr(options->dev, options->lladdr, NULL); |
| 432 | 432 |
return true; |
| ... | ... |
@@ -24,8 +24,8 @@ int set_lladdr(const char *ifname, const char *lladdr, |
| 24 | 24 |
#if defined(TARGET_LINUX) |
| 25 | 25 |
#ifdef CONFIG_FEATURE_IPROUTE |
| 26 | 26 |
openvpn_snprintf (cmd, sizeof (cmd), |
| 27 |
- IPROUTE_PATH " link set addr %s dev %s", |
|
| 28 |
- lladdr, ifname); |
|
| 27 |
+ "%s link set addr %s dev %s", |
|
| 28 |
+ iproute_path, lladdr, ifname); |
|
| 29 | 29 |
#else |
| 30 | 30 |
openvpn_snprintf (cmd, sizeof (cmd), |
| 31 | 31 |
IFCONFIG_PATH " %s hw ether %s", |
| ... | ... |
@@ -269,4 +269,11 @@ void configure_path (void); |
| 269 | 269 |
void get_user_pass_auto_userid (struct user_pass *up, const char *tag); |
| 270 | 270 |
#endif |
| 271 | 271 |
|
| 272 |
+/* |
|
| 273 |
+ * /sbin/ip path, may be overridden |
|
| 274 |
+ */ |
|
| 275 |
+#ifdef CONFIG_FEATURE_IPROUTE |
|
| 276 |
+extern const char *iproute_path; |
|
| 277 |
+#endif |
|
| 278 |
+ |
|
| 272 | 279 |
#endif |
| ... | ... |
@@ -71,6 +71,8 @@ openvpn \- secure IP tunnel daemon. |
| 71 | 71 |
[\ \fB\-\-dev\-type\fR\ \fIdevice\-type\fR\ ] |
| 72 | 72 |
[\ \fB\-\-dev\-node\fR\ \fInode\fR\ ] |
| 73 | 73 |
[\ \fB\-\-lladdr\fR\ \fIaddress\fR\ ] |
| 74 |
+[\ \fB\-\-user\fR\ \fIuser\fR\ ] |
|
| 75 |
+[\ \fB\-\-group\fR\ \fIgroup\fR\ ] |
|
| 74 | 76 |
.in -4 |
| 75 | 77 |
.ti +4 |
| 76 | 78 |
.hy |
| ... | ... |
@@ -164,6 +166,7 @@ openvpn \- secure IP tunnel daemon. |
| 164 | 164 |
[\ \fB\-\-inetd\fR\ \fI[wait|nowait]\ [progname]\fR\ ] |
| 165 | 165 |
[\ \fB\-\-ip\-win32\fR\ \fImethod\fR\ ] |
| 166 | 166 |
[\ \fB\-\-ipchange\fR\ \fIcmd\fR\ ] |
| 167 |
+[\ \fB\-\-iproute\fR\ \fIcmd\fR\ ] |
|
| 167 | 168 |
[\ \fB\-\-iroute\fR\ \fInetwork\ [netmask]\fR\ ] |
| 168 | 169 |
[\ \fB\-\-keepalive\fR\ \fIn\ m\fR\ ] |
| 169 | 170 |
[\ \fB\-\-key\-method\fR\ \fIm\fR\ ] |
| ... | ... |
@@ -923,6 +926,11 @@ Specify the link layer address, more commonly known as the MAC address. |
| 923 | 923 |
Only applied to TAP devices. |
| 924 | 924 |
.\"********************************************************* |
| 925 | 925 |
.TP |
| 926 |
+.B --iproute cmd |
|
| 927 |
+Set alternate command to execute instead of default iproute2 command. |
|
| 928 |
+May be used in order to execute OpenVPN in unprivileged environment. |
|
| 929 |
+.\"********************************************************* |
|
| 930 |
+.TP |
|
| 926 | 931 |
.B --ifconfig l rn |
| 927 | 932 |
Set TUN/TAP adapter parameters. |
| 928 | 933 |
.B l |
| ... | ... |
@@ -4306,6 +4314,14 @@ Remove a persistent tunnel. |
| 4306 | 4306 |
.B --dev tunX | tapX |
| 4307 | 4307 |
TUN/TAP device |
| 4308 | 4308 |
.\"********************************************************* |
| 4309 |
+.TP |
|
| 4310 |
+.B --user user |
|
| 4311 |
+Optional user to be owner of this tunnel. |
|
| 4312 |
+.\"********************************************************* |
|
| 4313 |
+.TP |
|
| 4314 |
+.B --group group |
|
| 4315 |
+Optional group to be owner of this tunnel. |
|
| 4316 |
+.\"********************************************************* |
|
| 4309 | 4317 |
.SS Windows-Specific Options: |
| 4310 | 4318 |
.\"********************************************************* |
| 4311 | 4319 |
.TP |
| ... | ... |
@@ -156,6 +156,9 @@ static const char usage_message[] = |
| 156 | 156 |
"--lladdr hw : Set the link layer address of the tap device.\n" |
| 157 | 157 |
"--topology t : Set --dev tun topology: 'net30', 'p2p', or 'subnet'.\n" |
| 158 | 158 |
"--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n" |
| 159 |
+#ifdef CONFIG_FEATURE_IPROUTE |
|
| 160 |
+ "--iproute cmd : Use this command instead of default " IPROUTE_PATH ".\n" |
|
| 161 |
+#endif |
|
| 159 | 162 |
"--ifconfig l rn : TUN: configure device to use IP address l as a local\n" |
| 160 | 163 |
" endpoint and rn as a remote endpoint. l & rn should be\n" |
| 161 | 164 |
" swapped on the other peer. l & rn must be private\n" |
| ... | ... |
@@ -591,6 +594,8 @@ static const char usage_message[] = |
| 591 | 591 |
"--rmtun : Remove a persistent tunnel.\n" |
| 592 | 592 |
"--dev tunX|tapX : tun/tap device\n" |
| 593 | 593 |
"--dev-type dt : Device type. See tunnel options above for details.\n" |
| 594 |
+ "--user user : User to set privilege to.\n" |
|
| 595 |
+ "--group group : Group to set privilege to.\n" |
|
| 594 | 596 |
#endif |
| 595 | 597 |
#ifdef ENABLE_PKCS11 |
| 596 | 598 |
"\n" |
| ... | ... |
@@ -3225,6 +3230,13 @@ add_option (struct options *options, |
| 3225 | 3225 |
VERIFY_PERMISSION (OPT_P_UP); |
| 3226 | 3226 |
options->tun_ipv6 = true; |
| 3227 | 3227 |
} |
| 3228 |
+#ifdef CONFIG_FEATURE_IPROUTE |
|
| 3229 |
+ else if (streq (p[0], "iproute") && p[1]) |
|
| 3230 |
+ {
|
|
| 3231 |
+ VERIFY_PERMISSION (OPT_P_UP); |
|
| 3232 |
+ iproute_path = p[1]; |
|
| 3233 |
+ } |
|
| 3234 |
+#endif |
|
| 3228 | 3235 |
else if (streq (p[0], "ifconfig") && p[1] && p[2]) |
| 3229 | 3236 |
{
|
| 3230 | 3237 |
VERIFY_PERMISSION (OPT_P_UP); |
| ... | ... |
@@ -777,7 +777,8 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s |
| 777 | 777 |
|
| 778 | 778 |
#if defined(TARGET_LINUX) |
| 779 | 779 |
#ifdef CONFIG_FEATURE_IPROUTE |
| 780 |
- buf_printf (&buf, IPROUTE_PATH " route add %s/%d via %s", |
|
| 780 |
+ buf_printf (&buf, "%s route add %s/%d via %s", |
|
| 781 |
+ iproute_path, |
|
| 781 | 782 |
network, |
| 782 | 783 |
count_netmask_bits(netmask), |
| 783 | 784 |
gateway); |
| ... | ... |
@@ -934,7 +935,8 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags |
| 934 | 934 |
|
| 935 | 935 |
#if defined(TARGET_LINUX) |
| 936 | 936 |
#ifdef CONFIG_FEATURE_IPROUTE |
| 937 |
- buf_printf (&buf, IPROUTE_PATH " route del %s/%d", |
|
| 937 |
+ buf_printf (&buf, "%s route del %s/%d", |
|
| 938 |
+ iproute_path, |
|
| 938 | 939 |
network, |
| 939 | 940 |
count_netmask_bits(netmask)); |
| 940 | 941 |
#else |
| ... | ... |
@@ -577,7 +577,8 @@ do_ifconfig (struct tuntap *tt, |
| 577 | 577 |
* Set the MTU for the device |
| 578 | 578 |
*/ |
| 579 | 579 |
openvpn_snprintf (command_line, sizeof (command_line), |
| 580 |
- IPROUTE_PATH " link set dev %s up mtu %d", |
|
| 580 |
+ "%s link set dev %s up mtu %d", |
|
| 581 |
+ iproute_path, |
|
| 581 | 582 |
actual, |
| 582 | 583 |
tun_mtu |
| 583 | 584 |
); |
| ... | ... |
@@ -590,7 +591,8 @@ do_ifconfig (struct tuntap *tt, |
| 590 | 590 |
* Set the address for the device |
| 591 | 591 |
*/ |
| 592 | 592 |
openvpn_snprintf (command_line, sizeof (command_line), |
| 593 |
- IPROUTE_PATH " addr add dev %s local %s peer %s", |
|
| 593 |
+ "%s addr add dev %s local %s peer %s", |
|
| 594 |
+ iproute_path, |
|
| 594 | 595 |
actual, |
| 595 | 596 |
ifconfig_local, |
| 596 | 597 |
ifconfig_remote_netmask |
| ... | ... |
@@ -599,7 +601,8 @@ do_ifconfig (struct tuntap *tt, |
| 599 | 599 |
system_check (command_line, es, S_FATAL, "Linux ip addr add failed"); |
| 600 | 600 |
} else {
|
| 601 | 601 |
openvpn_snprintf (command_line, sizeof (command_line), |
| 602 |
- IPROUTE_PATH " addr add dev %s %s/%d broadcast %s", |
|
| 602 |
+ "%s addr add dev %s %s/%d broadcast %s", |
|
| 603 |
+ iproute_path, |
|
| 603 | 604 |
actual, |
| 604 | 605 |
ifconfig_local, |
| 605 | 606 |
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 |
| 1162 | 1162 |
|
| 1163 | 1163 |
#ifdef TUNSETPERSIST |
| 1164 | 1164 |
|
| 1165 |
+/* |
|
| 1166 |
+ * This can be removed in future |
|
| 1167 |
+ * when all systems will use newer |
|
| 1168 |
+ * linux-headers |
|
| 1169 |
+ */ |
|
| 1170 |
+#ifndef TUNSETOWNER |
|
| 1171 |
+#define TUNSETOWNER _IOW('T', 204, int)
|
|
| 1172 |
+#endif |
|
| 1173 |
+#ifndef TUNSETGROUP |
|
| 1174 |
+#define TUNSETGROUP _IOW('T', 206, int)
|
|
| 1175 |
+#endif |
|
| 1176 |
+ |
|
| 1165 | 1177 |
void |
| 1166 |
-tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const struct tuntap_options *options) |
|
| 1178 |
+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) |
|
| 1167 | 1179 |
{
|
| 1168 | 1180 |
struct tuntap *tt; |
| 1169 | 1181 |
|
| ... | ... |
@@ -1174,6 +1189,26 @@ tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, |
| 1174 | 1174 |
open_tun (dev, dev_type, dev_node, ipv6, tt); |
| 1175 | 1175 |
if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0) |
| 1176 | 1176 |
msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); |
| 1177 |
+ if (username != NULL) |
|
| 1178 |
+ {
|
|
| 1179 |
+ struct user_state user_state; |
|
| 1180 |
+ |
|
| 1181 |
+ if (!get_user (username, &user_state)) |
|
| 1182 |
+ msg (M_ERR, "Cannot get user entry for %s", username); |
|
| 1183 |
+ else |
|
| 1184 |
+ if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0) |
|
| 1185 |
+ msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev); |
|
| 1186 |
+ } |
|
| 1187 |
+ if (groupname != NULL) |
|
| 1188 |
+ {
|
|
| 1189 |
+ struct group_state group_state; |
|
| 1190 |
+ |
|
| 1191 |
+ if (!get_group (groupname, &group_state)) |
|
| 1192 |
+ msg (M_ERR, "Cannot get group entry for %s", groupname); |
|
| 1193 |
+ else |
|
| 1194 |
+ if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0) |
|
| 1195 |
+ msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev); |
|
| 1196 |
+ } |
|
| 1177 | 1197 |
close_tun (tt); |
| 1178 | 1198 |
msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF")); |
| 1179 | 1199 |
} |
| ... | ... |
@@ -1185,6 +1220,19 @@ close_tun (struct tuntap *tt) |
| 1185 | 1185 |
{
|
| 1186 | 1186 |
if (tt) |
| 1187 | 1187 |
{
|
| 1188 |
+#ifdef CONFIG_FEATURE_IPROUTE |
|
| 1189 |
+ char command_line[256]; |
|
| 1190 |
+ /* |
|
| 1191 |
+ * Flush IP configuration for the device |
|
| 1192 |
+ */ |
|
| 1193 |
+ openvpn_snprintf (command_line, sizeof (command_line), |
|
| 1194 |
+ "%s addr flush dev %s", |
|
| 1195 |
+ iproute_path, |
|
| 1196 |
+ tt->actual_name |
|
| 1197 |
+ ); |
|
| 1198 |
+ msg (M_INFO, "%s", command_line); |
|
| 1199 |
+ system_check (command_line, NULL, S_FATAL, "Linux ip flush failed"); |
|
| 1200 |
+#endif |
|
| 1188 | 1201 |
close_tun_generic (tt); |
| 1189 | 1202 |
free (tt); |
| 1190 | 1203 |
} |
| ... | ... |
@@ -204,7 +204,8 @@ int write_tun (struct tuntap* tt, uint8_t *buf, int len); |
| 204 | 204 |
int read_tun (struct tuntap* tt, uint8_t *buf, int len); |
| 205 | 205 |
|
| 206 | 206 |
void tuncfg (const char *dev, const char *dev_type, const char *dev_node, |
| 207 |
- bool ipv6, int persist_mode, const struct tuntap_options *options); |
|
| 207 |
+ bool ipv6, int persist_mode, const char *username, |
|
| 208 |
+ const char *groupname, const struct tuntap_options *options); |
|
| 208 | 209 |
|
| 209 | 210 |
const char *guess_tuntap_dev (const char *dev, |
| 210 | 211 |
const char *dev_type, |