Project

General

Profile

Download (41.7 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 b1ad443d Scott Ullrich
/*
3 9a6d6728 Ermal
	openvpn.inc part of pfSense
4 33ab8aa5 Scott Ullrich
	
5
	Copyright (C) 2008 Scott Ullrich <sullrich@gmail.com>
6
	All rights reserved.
7
	
8 b1ad443d Scott Ullrich
	Copyright (C) 2006  Fernando Lemos
9
	All rights reserved.
10
11 33ab8aa5 Scott Ullrich
	This file was rewritten from scratch by Fernando Lemos but
12
	*MIGHT* contain code previously written by:
13
14 b1ad443d Scott Ullrich
	Copyright (C) 2005 Peter Allgeyer <allgeyer_AT_web.de>
15
	All rights reserved.
16
17
	Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
18
	All rights reserved.
19
20
	Redistribution and use in source and binary forms, with or without
21
	modification, are permitted provided that the following conditions are met:
22
23
	1. Redistributions of source code must retain the above copyright notices,
24
	   this list of conditions and the following disclaimer.
25
26
	2. Redistributions in binary form must reproduce the above copyright
27
	   notices, this list of conditions and the following disclaimer in the
28
	   documentation and/or other materials provided with the distribution.
29
30
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
32
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
	POSSIBILITY OF SUCH DAMAGE.
40 523855b0 Scott Ullrich
	
41
	DISABLE_PHP_LINT_CHECKING
42
	
43 2ec95f1f Renato Botelho
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/openvpn	/usr/bin/openssl	/sbin/ifconfig
44 523855b0 Scott Ullrich
	pfSense_MODULE:	openvpn
45 b1ad443d Scott Ullrich
46 523855b0 Scott Ullrich
*/
47 8dc3ef67 Scott Ullrich
require_once('config.inc');
48 32a7a1f6 Ermal Lu?i
require_once("certs.inc");
49 36df0acc Scott Ullrich
require_once('pfsense-utils.inc');
50 c61e4626 Ermal Lu?i
require_once("auth.inc");
51 8dc3ef67 Scott Ullrich
52 f2291484 jim-p
global $openvpn_prots;
53 6714bbdc jim-p
$openvpn_prots = array("UDP", "UDP6", "TCP", "TCP6");
54 702a4702 Scott Ullrich
55 f2291484 jim-p
global $openvpn_dev_mode;
56 691fbf14 Ermal Lu?i
$openvpn_dev_mode = array("tun", "tap");
57
58 3c11bd3c Matthew Grooms
/* 
59
 * The User Auth mode below is disabled because
60
 * OpenVPN erroneously requires that we provide
61
 * a CA configuration parameter. In this mode,
62
 * clients don't send a certificate so there is
63
 * no need for a CA. If we require that admins
64
 * provide one in the pfSense UI due to a bogus
65
 * requirement imposed by OpenVPN, it could be
66
 * considered very confusing ( I know I was ).
67
 *
68
 * -mgrooms
69
 */
70
71 f2291484 jim-p
global $openvpn_dh_lengths;
72 fe787fc7 Matthew Grooms
$openvpn_dh_lengths = array(
73
	1024, 2048, 4096 );
74
75 f2291484 jim-p
global $openvpn_cert_depths;
76 98963f27 jim-p
$openvpn_cert_depths = array(
77
	1 => "One (Client+Server)",
78
	2 => "Two (Client+Intermediate+Server)",
79
	3 => "Three (Client+2xIntermediate+Server)",
80
	4 => "Four (Client+3xIntermediate+Server)",
81
	5 => "Five (Client+4xIntermediate+Server)"
82
);
83
84 f2291484 jim-p
global $openvpn_server_modes;
85 3c11bd3c Matthew Grooms
$openvpn_server_modes = array(
86 4aa02281 Carlos Eduardo Ramos
	'p2p_tls' => gettext("Peer to Peer ( SSL/TLS )"),
87
	'p2p_shared_key' => gettext("Peer to Peer ( Shared Key )"),
88
	'server_tls' => gettext("Remote Access ( SSL/TLS )"),
89
	'server_user' => gettext("Remote Access ( User Auth )"),
90
	'server_tls_user' => gettext("Remote Access ( SSL/TLS + User Auth )"));
91 3c11bd3c Matthew Grooms
92 f2291484 jim-p
global $openvpn_client_modes;
93 3c11bd3c Matthew Grooms
$openvpn_client_modes = array(
94 4aa02281 Carlos Eduardo Ramos
	'p2p_tls' => gettext("Peer to Peer ( SSL/TLS )"),
95
	'p2p_shared_key' => gettext("Peer to Peer ( Shared Key )") );
96 3c11bd3c Matthew Grooms
97 edba1982 jim-p
global $openvpn_compression_modes;
98
$openvpn_compression_modes = array(
99 9ed52990 jim-p
	'' =>	gettext("No Preference"),
100 edba1982 jim-p
	'no' =>		gettext("Disabled - No Compression"),
101
	'adaptive' =>	gettext("Enabled with Adaptive Compression"),
102
	'yes' =>	gettext("Enabled without Adaptive Compression"));
103
104 3c11bd3c Matthew Grooms
function openvpn_create_key() {
105
106
	$fp = popen("/usr/local/sbin/openvpn --genkey --secret /dev/stdout 2>/dev/null", "r");
107
	if (!$fp)
108
		return false;
109
110
	$rslt = stream_get_contents($fp);
111
	pclose($fp);
112
113
	return $rslt;
114
}
115 d799787e Matthew Grooms
116 8411b218 Matthew Grooms
function openvpn_create_dhparams($bits) {
117 34bc1324 Matthew Grooms
118 2ec95f1f Renato Botelho
	$fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r");
119 34bc1324 Matthew Grooms
	if (!$fp)
120
		return false;
121
122
	$rslt = stream_get_contents($fp);
123
	pclose($fp);
124
125
	return $rslt;
126
}
127
128 d799787e Matthew Grooms
function openvpn_vpnid_used($vpnid) {
129 8be2d6d3 Ermal Luçi
	global $config;
130
131 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-server']))
132 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
133 f432e364 Matthew Grooms
			if ($vpnid == $settings['vpnid'])
134 d799787e Matthew Grooms
				return true;
135
136
	if (is_array($config['openvpn']['openvpn-client']))
137 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
138 f432e364 Matthew Grooms
			if ($vpnid == $settings['vpnid'])
139 d799787e Matthew Grooms
				return true;
140 04a6e900 Ermal Luçi
141 d799787e Matthew Grooms
	return false;
142
}
143
144
function openvpn_vpnid_next() {
145
146
	$vpnid = 1;
147
	while(openvpn_vpnid_used($vpnid))
148
		$vpnid++;
149
150
	return $vpnid;
151
}
152
153 49b76122 Renato Botelho
function openvpn_port_used($prot, $interface, $port, $curvpnid = 0) {
154 f432e364 Matthew Grooms
	global $config;
155
156 49b76122 Renato Botelho
	if (is_array($config['openvpn']['openvpn-server'])) {
157
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
158
			if (isset($settings['disable']))
159
				continue;
160
161
			if ($curvpnid != 0 && $curvpnid == $settings['vpnid'])
162
				continue;
163
164
			if ($port == $settings['local_port'] && $prot == $settings['protocol'] &&
165
				($interface == $settings['interface'] || $interface == "any" || $settings['interface'] == "any"))
166 f432e364 Matthew Grooms
				return $settings['vpnid'];
167 49b76122 Renato Botelho
		}
168
	}
169 f432e364 Matthew Grooms
170 49b76122 Renato Botelho
	if (is_array($config['openvpn']['openvpn-client'])) {
171
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
172
			if (isset($settings['disable']))
173
				continue;
174
175
			if ($curvpnid != 0 && $curvpnid == $settings['vpnid'])
176
				continue;
177
178
			if ($port == $settings['local_port'] && $prot == $settings['protocol'] &&
179
				($interface == $settings['interface'] || $interface == "any" || $settings['interface'] == "any"))
180 f432e364 Matthew Grooms
				return $settings['vpnid'];
181 49b76122 Renato Botelho
		}
182
	}
183 f432e364 Matthew Grooms
184
	return 0;
185
}
186
187 49b76122 Renato Botelho
function openvpn_port_next($prot, $interface = "wan") {
188 f432e364 Matthew Grooms
189
	$port = 1194;
190 49b76122 Renato Botelho
	while(openvpn_port_used($prot, $interface, $port))
191
		$port++;
192
	while(openvpn_port_used($prot, "any", $port))
193 f432e364 Matthew Grooms
		$port++;
194
195
	return $port;
196
}
197
198 d799787e Matthew Grooms
function openvpn_get_cipherlist() {
199
200
	$ciphers = array();
201 5a7cc1f9 Ermal
	$cipher_out = shell_exec('/usr/local/sbin/openvpn --show-ciphers | /usr/bin/grep "default key" | /usr/bin/awk \'{print $1, "(" $2 "-" $3 ")";}\'');
202 d799787e Matthew Grooms
	$cipher_lines = explode("\n", trim($cipher_out));
203
	sort($cipher_lines);
204
	foreach ($cipher_lines as $line) {
205
		$words = explode(' ', $line);
206
		$ciphers[$words[0]] = "{$words[0]} {$words[1]}";
207 8be2d6d3 Ermal Luçi
	}
208 4aa02281 Carlos Eduardo Ramos
	$ciphers["none"] = gettext("None (No Encryption)");
209 d799787e Matthew Grooms
	return $ciphers;
210
}
211
212 97d5b59b jim-p
function openvpn_get_digestlist() {
213
214
	$digests = array();
215
	$digest_out = shell_exec('/usr/local/sbin/openvpn --show-digests | /usr/bin/grep "digest size" | /usr/bin/awk \'{print $1, "(" $2 "-" $3 ")";}\'');
216
	$digest_lines = explode("\n", trim($digest_out));
217
	sort($digest_lines);
218
	foreach ($digest_lines as $line) {
219
		$words = explode(' ', $line);
220
		$digests[$words[0]] = "{$words[0]} {$words[1]}";
221
	}
222
	$digests["none"] = gettext("None (No Authentication)");
223
	return $digests;
224
}
225
226 582c58ae jim-p
function openvpn_get_engines() {
227
	$openssl_engines = array('none' => 'No Hardware Crypto Acceleration');
228 2ec95f1f Renato Botelho
	exec("/usr/bin/openssl engine -t -c", $openssl_engine_output);
229 349bf358 jim-p
	$openssl_engine_output = implode("\n", $openssl_engine_output);
230
	$openssl_engine_output = preg_replace("/\\n\\s+/", "|", $openssl_engine_output);
231
	$openssl_engine_output = explode("\n", $openssl_engine_output);
232
233 582c58ae jim-p
	foreach ($openssl_engine_output as $oeo) {
234 349bf358 jim-p
		$keep = true;
235
		$details = explode("|", $oeo);
236
		$engine = array_shift($details);
237 582c58ae jim-p
		$linematch = array();
238 349bf358 jim-p
		preg_match("/\((.*)\)\s(.*)/", $engine, $linematch);
239
		foreach ($details as $dt) {
240
			if (strpos($dt, "unavailable") !== FALSE)
241
				$keep = false;
242
			if (strpos($dt, "available") !== FALSE)
243
				continue;
244
			if (strpos($dt, "[") !== FALSE)
245
				$ciphers = trim($dt, "[]");
246
		}
247
		if (!empty($ciphers))
248
			$ciphers = " - " . $ciphers;
249
		if (strlen($ciphers) > 60)
250
			$ciphers = substr($ciphers, 0, 60) . " ... ";
251
		if ($keep)
252
			$openssl_engines[$linematch[1]] = $linematch[2] . $ciphers;
253 582c58ae jim-p
	}
254
	return $openssl_engines;
255
}
256
257
function openvpn_validate_engine($engine) {
258
	$engines = openvpn_get_engines();
259
	return array_key_exists($engine, $engines);
260
}
261
262 d799787e Matthew Grooms
function openvpn_validate_host($value, $name) {
263
	$value = trim($value);
264 3e2bd5de Ermal Lu?i
	if (empty($value) || (!is_domain($value) && !is_ipaddr($value)))
265 4aa02281 Carlos Eduardo Ramos
		return sprintf(gettext("The field '%s' must contain a valid IP address or domain name."), $name);
266 d799787e Matthew Grooms
	return false;
267 8dc3ef67 Scott Ullrich
}
268
269
function openvpn_validate_port($value, $name) {
270
	$value = trim($value);
271 3e2bd5de Ermal Lu?i
	if (empty($value) || !is_numeric($value) || $value < 0 || ($value > 65535))
272 4aa02281 Carlos Eduardo Ramos
		return sprintf(gettext("The field '%s' must contain a valid port, ranging from 0 to 65535."), $name);
273 b398bbca Martin Fuchs
	return false;
274 8dc3ef67 Scott Ullrich
}
275
276 a28d40cb jim-p
function openvpn_validate_cidr($value, $name, $multiple = false, $ipproto = "ipv4") {
277
	$value = trim($value);
278
	$error = false;
279
	if (empty($value))
280
		return false;
281
	$networks = explode(',', $value);
282
283
	if (!$multiple && (count($networks) > 1))
284
		return sprintf(gettext("The field '%s' must contain a single valid %s CIDR range."), $name, $ipproto);
285
286
	foreach ($networks as $network) {
287
		if ($ipproto == "ipv4")
288
			$error = !openvpn_validate_cidr_ipv4($network);
289
		else
290
			$error = !openvpn_validate_cidr_ipv6($network);
291
		if ($error)
292
			break;
293
	}
294
295
	if ($error)
296
		return sprintf(gettext("The field '%s' must contain only valid %s CIDR range(s) separated by commas."), $name, $ipproto);
297
	else
298
		return false;
299
}
300
301
function openvpn_validate_cidr_ipv4($value) {
302 8dc3ef67 Scott Ullrich
	$value = trim($value);
303
	if (!empty($value)) {
304
		list($ip, $mask) = explode('/', $value);
305 a28d40cb jim-p
		if (!is_ipaddrv4($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
306
			return false;
307 8dc3ef67 Scott Ullrich
	}
308 a28d40cb jim-p
	return true;
309
}
310
311
function openvpn_validate_cidr_ipv6($value) {
312
	$value = trim($value);
313
	if (!empty($value)) {
314
		list($ipv6, $prefix) = explode('/', $value);
315
		if (empty($prefix))
316
			$prefix = "128";
317
		if (!is_ipaddrv6($ipv6) or !is_numeric($prefix) or ($prefix > 128) or ($prefix < 0))
318
			return false;
319
	}
320
	return true;
321 afb07cf1 Scott Ullrich
}
322
323 d799787e Matthew Grooms
function openvpn_add_dhcpopts(& $settings, & $conf) {
324 afb07cf1 Scott Ullrich
325 d799787e Matthew Grooms
	if (!empty($settings['dns_domain'])) 
326
		$conf .= "push \"dhcp-option DOMAIN {$settings['dns_domain']}\"\n";
327 add2e3f7 Scott Ullrich
328 d799787e Matthew Grooms
	if (!empty($settings['dns_server1']))
329
		$conf .= "push \"dhcp-option DNS {$settings['dns_server1']}\"\n";
330
	if (!empty($settings['dns_server2']))
331
		$conf .= "push \"dhcp-option DNS {$settings['dns_server2']}\"\n";
332
	if (!empty($settings['dns_server3']))
333
		$conf .= "push \"dhcp-option DNS {$settings['dns_server3']}\"\n";
334
	if (!empty($settings['dns_server4']))
335
		$conf .= "push \"dhcp-option DNS {$settings['dns_server4']}\"\n";
336 f9927473 Scott Ullrich
337 d799787e Matthew Grooms
	if (!empty($settings['ntp_server1']))
338 c7f70dbc Chris Buechler
		$conf .= "push \"dhcp-option NTP {$settings['ntp_server1']}\"\n";
339 d799787e Matthew Grooms
	if (!empty($settings['ntp_server2']))
340 c7f70dbc Chris Buechler
		$conf .= "push \"dhcp-option NTP {$settings['ntp_server2']}\"\n";
341 f9927473 Scott Ullrich
342 d799787e Matthew Grooms
	if ($settings['netbios_enable']) {
343 add2e3f7 Scott Ullrich
344 095a95ae Matthew Grooms
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0))
345
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
346
		if (!empty($settings['dhcp_nbtscope'])) 
347 d799787e Matthew Grooms
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
348 8dc3ef67 Scott Ullrich
349 d799787e Matthew Grooms
		if (!empty($settings['wins_server1']))
350
			$conf .= "push \"dhcp-option WINS {$settings['wins_server1']}\"\n";
351
		if (!empty($settings['wins_server2']))
352
			$conf .= "push \"dhcp-option WINS {$settings['wins_server2']}\"\n";
353 add2e3f7 Scott Ullrich
354 d799787e Matthew Grooms
		if (!empty($settings['nbdd_server1']))
355
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server1']}\"\n";
356
	}
357 8dc3ef67 Scott Ullrich
358 d799787e Matthew Grooms
	if ($settings['gwredir']) 
359
		$conf .= "push \"redirect-gateway def1\"\n";
360
}
361 24012690 Scott Ullrich
362 d799787e Matthew Grooms
function openvpn_add_custom(& $settings, & $conf) {
363 add2e3f7 Scott Ullrich
364 d799787e Matthew Grooms
	if ($settings['custom_options']) {
365 8dc3ef67 Scott Ullrich
366 d799787e Matthew Grooms
		$options = explode(';', $settings['custom_options']);
367
368
		if (is_array($options)) {
369
			foreach ($options as $option)
370
				$conf .= "$option\n";
371
		} else
372
			$conf .= "{$settings['custom_options']}\n";
373 add2e3f7 Scott Ullrich
	}
374
}
375
376 691fbf14 Ermal Lu?i
function openvpn_add_keyfile(& $data, & $conf, $mode_id, $directive, $opt = "") {
377 d799787e Matthew Grooms
	global $g;
378 add2e3f7 Scott Ullrich
379 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.{$directive}";
380 a8f538a8 jim-p
	openvpn_create_dirs();
381 d799787e Matthew Grooms
	file_put_contents($fpath, base64_decode($data));
382 f9ac3784 Ermal Lu?i
	//chown($fpath, 'nobody');
383
	//chgrp($fpath, 'nobody');
384 6f27412f Ermal Lu?i
	@chmod($fpath, 0600);
385 d799787e Matthew Grooms
386 691fbf14 Ermal Lu?i
	$conf .= "{$directive} {$fpath} {$opt}\n";
387 4eefa6e8 Scott Ullrich
}
388
389 fc05822b jim-p
function openvpn_reconfigure($mode, $settings) {
390 add2e3f7 Scott Ullrich
	global $g, $config;
391 afb07cf1 Scott Ullrich
392 93a0a028 Ermal Luçi
	if (empty($settings))
393
		return;
394 a1cab2c7 Ermal
	if (isset($settings['disable'])) 
395 4eefa6e8 Scott Ullrich
		return;
396 a8f538a8 jim-p
	openvpn_create_dirs();
397 fdd725f0 Ermal Luçi
	/*
398 d799787e Matthew Grooms
	 * NOTE: Deleting tap devices causes spontaneous reboots. Instead,
399
	 * we use a vpnid number which is allocated for a particular client
400
	 * or server configuration. ( see openvpn_vpnid_next() )
401 fdd725f0 Ermal Luçi
	 */
402 8874c692 Ermal Luçi
403 d799787e Matthew Grooms
	$vpnid = $settings['vpnid'];
404
	$mode_id = $mode.$vpnid;
405 8874c692 Ermal Luçi
406 4936ff53 jim-p
	if (isset($settings['dev_mode']))
407
		$tunname = "{$settings['dev_mode']}{$vpnid}";
408 bd7ca506 jim-p
	else {	/* defaults to tun */
409
		$tunname = "tun{$vpnid}";
410 4936ff53 jim-p
		$settings['dev_mode'] = "tun";
411 691fbf14 Ermal Lu?i
	}
412
413 bd7ca506 jim-p
	if ($mode == "server")
414
		$devname = "ovpns{$vpnid}";
415
	else
416
		$devname = "ovpnc{$vpnid}";
417 8874c692 Ermal Luçi
418 bd7ca506 jim-p
	/* is our device already configured */
419 4a97aa34 Ermal
	if (!does_interface_exist($devname)) {
420 dc408939 Matthew Grooms
421 bd7ca506 jim-p
		/* create the tap device if required */
422
		if (!file_exists("/dev/{$tunname}"))
423 873c1701 Renato Botelho
			exec("/sbin/ifconfig " . escapeshellarg($tunname) . " create");
424 98872d89 Ermal Luçi
425 bd7ca506 jim-p
		/* rename the device */
426 873c1701 Renato Botelho
		mwexec("/sbin/ifconfig " . escapeshellarg($tunname) . " name " . escapeshellarg($devname));
427 095a95ae Matthew Grooms
428 bd7ca506 jim-p
		/* add the device to the openvpn group */
429 873c1701 Renato Botelho
		mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " group openvpn");
430 dc408939 Matthew Grooms
	}
431 d799787e Matthew Grooms
432 dc408939 Matthew Grooms
	$pfile = $g['varrun_path'] . "/openvpn_{$mode_id}.pid";
433 6714bbdc jim-p
	$proto = strtolower($settings['protocol']);
434
	if (substr($settings['protocol'], 0, 3) == "TCP")
435
			$proto = "{$proto}-{$mode}";
436 4936ff53 jim-p
	$dev_mode = $settings['dev_mode'];
437 c0cf27aa Scott Ullrich
	$cipher = $settings['crypto'];
438 97d5b59b jim-p
	// OpenVPN defaults to SHA1, so use it when unset to maintain compatibility.
439
	$digest = !empty($settings['digest']) ? $settings['digest'] : "SHA1";
440 d799787e Matthew Grooms
441 47c48e28 smos
	$interface = get_failover_interface($settings['interface']);
442 d7a0c22a bcyrill
	$ipaddr = $settings['ipaddr'];
443
	$ipaddrv6 = $settings['ipaddrv6'];
444 d799787e Matthew Grooms
445 67b0902f pierrepomes
	// If a specific ip address (VIP) is requested, use it.
446
	// Otherwise, if a specific interface is requested, use it
447
	// If "any" interface was selected, local directive will be ommited.
448 97ffc513 Seth Mos
	if (is_ipaddrv4($ipaddr)) {
449 67b0902f pierrepomes
		$iface_ip=$ipaddr;
450 3d06e8f0 pierrepomes
	} else {
451 67b0902f pierrepomes
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
452 507af8dd pierrepomes
			$iface_ip=get_interface_ip($interface);
453 67b0902f pierrepomes
		}
454 47c48e28 smos
	}
455
	if (is_ipaddrv6($ipaddrv6)) {
456
		$iface_ipv6=$ipaddrv6;
457
	} else {
458 97ffc513 Seth Mos
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
459
			$iface_ipv6=get_interface_ipv6($interface);
460
		}
461 3d06e8f0 pierrepomes
	}
462 d799787e Matthew Grooms
463 bd7ca506 jim-p
	$conf  = "dev {$devname}\n";
464 4936ff53 jim-p
	$conf .= "dev-type {$settings['dev_mode']}\n";
465 97ffc513 Seth Mos
	switch($settings['dev_mode']) {
466
		case "tun":
467
			$conf .= "tun-ipv6\n";
468
			break;
469
	}
470 bd7ca506 jim-p
	$conf .= "dev-node /dev/{$tunname}\n";
471 3c11bd3c Matthew Grooms
	$conf .= "writepid {$pfile}\n";
472
	$conf .= "#user nobody\n";
473
	$conf .= "#group nobody\n";
474 d1014c18 Chris Buechler
	$conf .= "script-security 3\n";
475 3c11bd3c Matthew Grooms
	$conf .= "daemon\n";
476
	$conf .= "keepalive 10 60\n";
477
	$conf .= "ping-timer-rem\n";
478
	$conf .= "persist-tun\n";
479
	$conf .= "persist-key\n";
480
	$conf .= "proto {$proto}\n";
481
	$conf .= "cipher {$cipher}\n";
482 97d5b59b jim-p
	$conf .= "auth {$digest}\n";
483 8d964cea Ermal
	$conf .= "up /usr/local/sbin/ovpn-linkup\n";
484
	$conf .= "down /usr/local/sbin/ovpn-linkdown\n";
485 1492e02c Ermal
	if (file_exists("/usr/local/sbin/openvpn.attributes.sh")) {
486 a1b9105b jim-p
		switch($settings['mode']) {
487
			case 'server_user':
488
			case 'server_tls_user':
489
				$conf .= "client-connect /usr/local/sbin/openvpn.attributes.sh\n";
490
				$conf .= "client-disconnect /usr/local/sbin/openvpn.attributes.sh\n";
491
				break;
492
		}
493 1492e02c Ermal
	}
494 3c11bd3c Matthew Grooms
495 6714bbdc jim-p
	/* Determine the local IP to use - and make sure it matches with the selected protocol. */
496
	if (is_ipaddrv4($iface_ip) && (stristr($settings['protocol'], "6") === false)) {
497
		$conf .= "local {$iface_ip}\n";
498
	} elseif (is_ipaddrv6($iface_ipv6) && (stristr($settings['protocol'], "6") !== false)) {
499
		$conf .= "local {$iface_ipv6}\n";
500 97ffc513 Seth Mos
	}
501 d799787e Matthew Grooms
502 582c58ae jim-p
	if (openvpn_validate_engine($settings['engine']) && ($settings['engine'] != "none"))
503
		$conf .= "engine {$settings['engine']}\n";
504
505 67b0902f pierrepomes
	// server specific settings
506 8dc3ef67 Scott Ullrich
	if ($mode == 'server') {
507 d799787e Matthew Grooms
508 5dc6c910 jim-p
		list($ip, $cidr) = explode('/', $settings['tunnel_network']);
509 97ffc513 Seth Mos
		list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
510 5dc6c910 jim-p
		$mask = gen_subnet_mask($cidr);
511 8dc3ef67 Scott Ullrich
512 3c11bd3c Matthew Grooms
		// configure tls modes
513
		switch($settings['mode']) {
514
			case 'p2p_tls':
515
			case 'server_tls':
516 e62e2f8b Ermal Lu?i
			case 'server_user':
517 3c11bd3c Matthew Grooms
			case 'server_tls_user':
518 d799787e Matthew Grooms
				$conf .= "tls-server\n";
519 3c11bd3c Matthew Grooms
				break;
520 8dc3ef67 Scott Ullrich
		}
521 d799787e Matthew Grooms
522 3c11bd3c Matthew Grooms
		// configure p2p/server modes
523
		switch($settings['mode']) {
524 6c9cf466 jim-p
			case 'p2p_tls':
525 5dc6c910 jim-p
				// If the CIDR is less than a /30, OpenVPN will complain if you try to
526
				//  use the server directive. It works for a single client without it.
527
				//  See ticket #1417
528 74a556a3 jim-p
				if (!empty($ip) && !empty($mask) && ($cidr < 30)) {
529 5dc6c910 jim-p
					$conf .= "server {$ip} {$mask}\n";
530
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
531 a0e3ee98 jim-p
					if(is_ipaddr($ipv6))
532
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
533 5dc6c910 jim-p
				}
534 3c11bd3c Matthew Grooms
			case 'p2p_shared_key':
535 74a556a3 jim-p
				if (!empty($ip) && !empty($mask)) {
536 91c44185 jim-p
					list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
537 459e9333 jim-p
					if ($settings['dev_mode'] == 'tun')
538
						$conf .= "ifconfig {$ip1} {$ip2}\n";
539
					else
540
						$conf .= "ifconfig {$ip1} {$mask}\n";
541 1ab6bdb5 jim-p
				}
542 a0e3ee98 jim-p
				if (!empty($ipv6) && !empty($prefix)) {
543 91c44185 jim-p
					list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
544 a0e3ee98 jim-p
					if ($settings['dev_mode'] == 'tun')
545
						$conf .= "ifconfig-ipv6 {$ipv6_1} {$ipv6_2}\n";
546
					else
547 60f501ec Phil Davis
						$conf .= "ifconfig-ipv6 {$ipv6_1} {$prefix}\n";
548 a0e3ee98 jim-p
				}
549 3c11bd3c Matthew Grooms
				break;
550
			case 'server_tls':
551
			case 'server_user':
552
			case 'server_tls_user':
553 74a556a3 jim-p
				if (!empty($ip) && !empty($mask)) {
554 1ab6bdb5 jim-p
					$conf .= "server {$ip} {$mask}\n";
555
					if(is_ipaddr($ipv6))
556
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
557
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
558
				} else {
559
					if ($settings['serverbridge_dhcp']) {
560
						if ((!empty($settings['serverbridge_interface'])) && (strcmp($settings['serverbridge_interface'], "none"))) {
561
							$biface_ip=get_interface_ip($settings['serverbridge_interface']);
562
							$biface_sm=gen_subnet_mask(get_interface_subnet($settings['serverbridge_interface']));
563
							if (is_ipaddrv4($biface_ip) && is_ipaddrv4($settings['serverbridge_dhcp_start']) && is_ipaddrv4($settings['serverbridge_dhcp_end'])) {
564
								$conf .= "server-bridge {$biface_ip} {$biface_sm} {$settings['serverbridge_dhcp_start']} {$settings['serverbridge_dhcp_end']}\n";
565 cb4f4ea9 jim-p
								$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
566 1ab6bdb5 jim-p
							} else {
567
								$conf .= "mode server\n";
568
							}
569
						} else {
570
							$conf .= "mode server\n";
571
						}
572
					}
573
				}
574 3c11bd3c Matthew Grooms
				break;
575 8dc3ef67 Scott Ullrich
		}
576
577 3c11bd3c Matthew Grooms
		// configure user auth modes
578
		switch($settings['mode']) {
579
			case 'server_user':
580
				$conf .= "client-cert-not-required\n";
581
			case 'server_tls_user':
582 9eced774 jim-p
				/* username-as-common-name is not compatible with server-bridge */
583
				if (stristr($conf, "server-bridge") === false)
584
					$conf .= "username-as-common-name\n";
585 8a47c190 Ermal Lu?i
				if (!empty($settings['authmode'])) {
586 5e28dad4 Ermal
					$strictusercn = "false";
587 53d41b68 Erik Fonnesbeck
					if ($settings['strictusercn'])
588 5e28dad4 Ermal
						$strictusercn = "true";
589 57ab9f7d Ermal
					$conf .= "auth-user-pass-verify \"/usr/local/sbin/ovpn_auth_verify user '{$settings['authmode']}' {$strictusercn} {$mode_id}\" via-env\n";
590 e8a58de4 Ermal Lu?i
				}
591 3c11bd3c Matthew Grooms
				break;
592 8dc3ef67 Scott Ullrich
		}
593 41936acc jim-p
		if (!isset($settings['cert_depth']) && (strstr($settings['mode'], 'tls')))
594
			$settings['cert_depth'] = 1;
595 98963f27 jim-p
		if (is_numeric($settings['cert_depth'])) {
596
			$cert = lookup_cert($settings['certref']);
597 b95b40a1 Ermal
			/* XXX: Seems not used at all! */
598
			$servercn = urlencode(cert_get_cn($cert['crt']));
599 f931befd jim-p
			$conf .= "tls-verify \"/usr/local/sbin/ovpn_auth_verify tls '{$servercn}' {$settings['cert_depth']}\"\n";
600 98963f27 jim-p
		}
601 8dc3ef67 Scott Ullrich
602 63084885 Matthew Grooms
		// The local port to listen on
603 d799787e Matthew Grooms
		$conf .= "lport {$settings['local_port']}\n";
604 c0cf27aa Scott Ullrich
605 63084885 Matthew Grooms
		// The management port to listen on
606 71ca2cb2 Ermal
		// Use unix socket to overcome the problem on any type of server
607
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
608
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
609 63084885 Matthew Grooms
610 3c11bd3c Matthew Grooms
		if ($settings['maxclients'])
611 d799787e Matthew Grooms
			$conf .= "max-clients {$settings['maxclients']}\n";
612
613 3c11bd3c Matthew Grooms
		// Can we push routes
614
		if ($settings['local_network']) {
615 a28d40cb jim-p
			$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
616 3c11bd3c Matthew Grooms
		}
617 787de45a Seth Mos
		if ($settings['local_networkv6']) {
618 a28d40cb jim-p
			$conf .= openvpn_gen_routes($settings['local_networkv6'], "ipv6", true);
619 787de45a Seth Mos
		}
620 3c11bd3c Matthew Grooms
621
		switch($settings['mode']) {
622
			case 'server_tls':
623
			case 'server_user':
624
			case 'server_tls_user':
625 5d8cd81a jim-p
				// Configure client dhcp options
626 3c11bd3c Matthew Grooms
				openvpn_add_dhcpopts($settings, $conf);
627 5d8cd81a jim-p
				if ($settings['client2client'])
628
					$conf .= "client-to-client\n";
629 3c11bd3c Matthew Grooms
				break;
630
		}
631 bca35cff jim-p
		if (isset($settings['duplicate_cn']))
632
			$conf .= "duplicate-cn\n";
633 d799787e Matthew Grooms
	}
634
635 3c11bd3c Matthew Grooms
	// client specific settings
636 d799787e Matthew Grooms
637 3c11bd3c Matthew Grooms
	if ($mode == 'client') {
638 d799787e Matthew Grooms
639 3c11bd3c Matthew Grooms
		// configure p2p mode
640
		switch($settings['mode']) {
641
			case 'p2p_tls':
642
				$conf .= "tls-client\n";
643
			case 'shared_key':
644
				$conf .= "client\n";
645
				break;
646
		}
647 d799787e Matthew Grooms
648 e3924384 jim-p
		// If there is no bind option at all (ip and/or port), add "nobind" directive
649
		//  Otherwise, use the local port if defined, failing that, use lport 0 to 
650
		//  ensure a random source port.
651
		if ((empty($iface_ip)) && (!$settings['local_port']))
652
			$conf .= "nobind\n";
653
		elseif ($settings['local_port'])
654
			$conf .= "lport {$settings['local_port']}\n";
655
		else
656
			$conf .= "lport 0\n";
657 5708241f jim-p
658 4b887ef4 jim-p
		// Use unix socket to overcome the problem on any type of server
659
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
660 48a458d2 pierrepomes
661 3c11bd3c Matthew Grooms
		// The remote server
662
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
663
664 d799787e Matthew Grooms
		if (!empty($settings['use_shaper']))
665
			$conf .= "shaper {$settings['use_shaper']}\n";
666 ee506044 Scott Ullrich
667 d799787e Matthew Grooms
		if (!empty($settings['tunnel_network'])) {
668
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
669 8dc3ef67 Scott Ullrich
			$mask = gen_subnet_mask($mask);
670 91c44185 jim-p
			list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
671 459e9333 jim-p
			if ($settings['dev_mode'] == 'tun')
672
				$conf .= "ifconfig {$ip2} {$ip1}\n";
673
			else
674
				$conf .= "ifconfig {$ip2} {$mask}\n";
675 8dc3ef67 Scott Ullrich
		}
676 d799787e Matthew Grooms
677 a0e3ee98 jim-p
		if (!empty($settings['tunnel_networkv6'])) {
678
			list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
679 91c44185 jim-p
			list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
680 a0e3ee98 jim-p
			if ($settings['dev_mode'] == 'tun')
681
				$conf .= "ifconfig-ipv6 {$ipv6_2} {$ipv6_1}\n";
682
			else
683 60f501ec Phil Davis
				$conf .= "ifconfig-ipv6 {$ipv6_2} {$prefix}\n";
684 a0e3ee98 jim-p
		}
685
686 5f242576 PiBa-NL
		if ($settings['auth_user'] && $settings['auth_pass']) {
687
			$up_file = "{$g['varetc_path']}/openvpn/{$mode_id}.up";
688
			$conf .= "auth-user-pass {$up_file}\n";
689
			$userpass = "{$settings['auth_user']}\n";
690
			$userpass .= "{$settings['auth_pass']}\n";
691
			file_put_contents($up_file, $userpass);
692
		}
693
		
694 762a24a3 Ermal Lu?i
		if ($settings['proxy_addr']) {
695
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
696
			if ($settings['proxy_authtype'] != "none") {
697
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
698
				$proxypas = "{$settings['proxy_user']}\n";
699
				$proxypas .= "{$settings['proxy_passwd']}\n";
700
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
701
			}
702
			$conf .= " \n";
703
		}
704 8dc3ef67 Scott Ullrich
	}
705
706 17c98ba9 jim-p
	// Add a remote network route if set, and only for p2p modes.
707 54285411 jim-p
	if ((substr($settings['mode'], 0, 3) == "p2p") && (openvpn_validate_cidr($settings['remote_network'], "", true, "ipv4") === FALSE)) {
708 a28d40cb jim-p
		$conf .= openvpn_gen_routes($settings['remote_network'], "ipv4", false);
709 8dc3ef67 Scott Ullrich
	}
710 4856df9b jim-p
	// Add a remote network route if set, and only for p2p modes.
711 54285411 jim-p
	if ((substr($settings['mode'], 0, 3) == "p2p") && (openvpn_validate_cidr($settings['remote_networkv6'], "", true, "ipv6") === FALSE)) {
712 a28d40cb jim-p
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false);
713 4856df9b jim-p
	}
714 afb07cf1 Scott Ullrich
715 d799787e Matthew Grooms
	// Write the settings for the keys
716 3c11bd3c Matthew Grooms
	switch($settings['mode']) {
717
		case 'p2p_shared_key':
718
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
719
			break;
720
		case 'p2p_tls':
721
		case 'server_tls':
722
		case 'server_tls_user':
723 e62e2f8b Ermal Lu?i
		case 'server_user':
724 3c11bd3c Matthew Grooms
			$ca = lookup_ca($settings['caref']);
725
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
726
			$cert = lookup_cert($settings['certref']);
727
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
728
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
729
			if ($mode == 'server')
730 fe787fc7 Matthew Grooms
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
731 6db02381 jim-p
			if (!empty($settings['crlref'])) {
732
				$crl = lookup_crl($settings['crlref']);
733 cfcc6994 jim-p
				crl_update($crl);
734 6db02381 jim-p
				openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify");
735
			}
736 db746ce2 Ermal Lu?i
			if ($settings['tls']) {
737 756720e2 Pierre POMES
				if ($mode == "server") 
738 db746ce2 Ermal Lu?i
					$tlsopt = 0;
739
				else
740
					$tlsopt = 1;
741
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
742
			}
743 3c11bd3c Matthew Grooms
			break;
744 8dc3ef67 Scott Ullrich
	}
745
746 edba1982 jim-p
	if (!empty($settings['compression']))
747
		$conf .= "comp-lzo {$settings['compression']}\n";
748 d799787e Matthew Grooms
749
	if ($settings['passtos'])
750
		$conf .= "passtos\n";
751
752
	if ($settings['resolve_retry'])
753
		$conf .= "resolv-retry infinite\n";
754
755
	if ($settings['dynamic_ip']) {
756
		$conf .= "persist-remote-ip\n";
757
		$conf .= "float\n";
758 8dc3ef67 Scott Ullrich
	}
759 afb07cf1 Scott Ullrich
760 ee55ce7d jim-p
	if ($settings['topology_subnet']) {
761
		$conf .= "topology subnet\n";
762
	}
763
764 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
765
766 a8f538a8 jim-p
	openvpn_create_dirs();
767 938fc5b0 Ermal
	$fpath = "{$g['varetc_path']}/openvpn/{$mode_id}.conf";
768 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
769 938fc5b0 Ermal
	unset($conf);
770 be00850b Phil Davis
	$fpath = "{$g['varetc_path']}/openvpn/{$mode_id}.interface";
771
	file_put_contents($fpath, $interface);
772 f9ac3784 Ermal Lu?i
	//chown($fpath, 'nobody');
773
	//chgrp($fpath, 'nobody');
774 6f27412f Ermal Lu?i
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
775 be00850b Phil Davis
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.interface", 0600);
776 6f27412f Ermal Lu?i
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
777
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
778
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
779 d799787e Matthew Grooms
}
780
781 fc05822b jim-p
function openvpn_restart($mode, $settings) {
782 d799787e Matthew Grooms
	global $g, $config;
783
784
	$vpnid = $settings['vpnid'];
785
	$mode_id = $mode.$vpnid;
786
787 76369bfc Matthew Grooms
	/* kill the process if running */
788 705c8ec9 Matthew Grooms
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
789 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
790 705c8ec9 Matthew Grooms
791 76369bfc Matthew Grooms
		/* read the pid file */
792
		$pid = rtrim(file_get_contents($pfile));
793
		unlink($pfile);
794 705c8ec9 Matthew Grooms
795 76369bfc Matthew Grooms
		/* send a term signal to the process */
796
		posix_kill($pid, SIGTERM);
797
798
		/* wait until the process exits */
799
		while(posix_kill($pid, 0))
800
			usleep(250000);
801
	}
802 d799787e Matthew Grooms
803 a1cab2c7 Ermal
	if (isset($settings['disable']))
804 d799787e Matthew Grooms
		return;
805
806 260f267e jim-p
	/* Do not start a client if we are a CARP backup on this vip! */
807 0c21eb70 Ermal
	if (($mode == "client") && (strstr($settings['interface'], "_vip") && get_carp_interface_status($settings['interface']) == "BACKUP"))
808 9ea0cb90 jim-p
		return;
809 330ecea1 Shahid Sheikh
		
810
	/* Check if client is bound to a gateway group */    
811
	$a_groups = return_gateway_groups_array();
812
	if (is_array($a_groups[$settings['interface']])) {
813
	/* the interface is a gateway group. If a vip is defined and its a CARP backup then do not start */
814
		if (($a_groups[$settings['interface']][0]['vip'] <> "") && (get_carp_interface_status($a_groups[$settings['interface']][0]['vip']) == "BACKUP"))
815
			return;
816
	}
817 9ea0cb90 jim-p
818 705c8ec9 Matthew Grooms
	/* start the new process */
819 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
820 91c44185 jim-p
	openvpn_clear_route($mode, $settings);
821 873c1701 Renato Botelho
	mwexec_bg("/usr/local/sbin/openvpn --config " . escapeshellarg($fpath));
822 847cd48d Ermal
823
	if (!$g['booting'])
824
		send_event("filter reload");
825 afb07cf1 Scott Ullrich
}
826
827 dc408939 Matthew Grooms
function openvpn_delete($mode, & $settings) {
828 d799787e Matthew Grooms
	global $g, $config;
829
830
	$vpnid = $settings['vpnid'];
831
	$mode_id = $mode.$vpnid;
832
833 da601f8e PiBa-NL
	if (isset($settings['dev_mode']))
834
		$tunname = "{$settings['dev_mode']}{$vpnid}";
835
	else {  /* defaults to tun */
836
		$tunname = "tun{$vpnid}";
837
	}
838
839 095a95ae Matthew Grooms
	if ($mode == "server")
840
		$devname = "ovpns{$vpnid}";
841
	else
842
		$devname = "ovpnc{$vpnid}";
843 dc408939 Matthew Grooms
844 76369bfc Matthew Grooms
	/* kill the process if running */
845 dc408939 Matthew Grooms
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
846 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
847 dc408939 Matthew Grooms
848 76369bfc Matthew Grooms
		/* read the pid file */
849
		$pid = trim(file_get_contents($pfile));
850
		unlink($pfile);
851
852
		/* send a term signal to the process */
853
		posix_kill($pid, SIGTERM);
854
	}
855 705c8ec9 Matthew Grooms
856 095a95ae Matthew Grooms
	/* remove the device from the openvpn group */
857 873c1701 Renato Botelho
	mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " -group openvpn");
858 095a95ae Matthew Grooms
859 dc408939 Matthew Grooms
	/* restore the original adapter name */
860 873c1701 Renato Botelho
	mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " name " . escapeshellarg($tunname));
861 dc408939 Matthew Grooms
862
	/* remove the configuration files */
863 873c1701 Renato Botelho
	array_map('unlink', glob("{$g['varetc_path']}/openvpn/{$mode_id}.*"));
864 d799787e Matthew Grooms
}
865 afb07cf1 Scott Ullrich
866 de85521a jim-p
function openvpn_cleanup_csc($common_name) {
867
	global $g, $config;
868
	if (empty($common_name))
869
		return;
870
	$fpath = "{$g['varetc_path']}/openvpn-csc/" . basename($common_name);
871
	if (is_file($fpath))
872
		unlink_if_exists($fpath);
873
	return;
874
}
875
876 dc408939 Matthew Grooms
function openvpn_resync_csc(& $settings) {
877 8dc3ef67 Scott Ullrich
	global $g, $config;
878
879 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
880 8dc3ef67 Scott Ullrich
881 a1cab2c7 Ermal
	if (isset($settings['disable'])) {
882 d799787e Matthew Grooms
		unlink_if_exists($fpath);
883 c876662c Scott Ullrich
		return;
884
	}
885 a8f538a8 jim-p
	openvpn_create_dirs();
886 d799787e Matthew Grooms
887 8dc3ef67 Scott Ullrich
	$conf = '';
888 d799787e Matthew Grooms
	if ($settings['block'])
889
		$conf .= "disable\n";
890
891
	if ($settings['push_reset'])
892
		$conf .= "push-reset\n";
893
894
	if (!empty($settings['tunnel_network'])) {
895
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
896 96033063 Erik Fonnesbeck
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
897 298fe5ae jim-p
		$serverip = long2ip32($baselong + 1);
898
		$clientip = long2ip32($baselong + 2);
899
		/* Because this is being pushed, the order from the client's point of view. */
900 d9c96fb1 jim-p
		if ($settings['dev_mode'] != 'tap')
901
			$conf .= "ifconfig-push {$clientip} {$serverip}\n";
902 e052047d jim-p
		else
903
			$conf .= "ifconfig-push {$clientip} {$mask}\n";
904 8dc3ef67 Scott Ullrich
	}
905 6d031071 Martin Fuchs
906 5c427ce7 jim-p
	if ($settings['local_network']) {
907
		$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
908
	}
909
	if ($settings['local_networkv6']) {
910
		$conf .= openvpn_gen_routes($settings['local_networkv6'], "ipv6", true);
911
	}
912
913
	// Add a remote network iroute if set
914
	if (openvpn_validate_cidr($settings['remote_network'], "", true, "ipv4") === FALSE) {
915
		$conf .= openvpn_gen_routes($settings['remote_network'], "ipv4", false, true);
916
	}
917
	// Add a remote network iroute if set
918
	if (openvpn_validate_cidr($settings['remote_networkv6'], "", true, "ipv6") === FALSE) {
919
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false, true);
920
	}
921
922 d799787e Matthew Grooms
	openvpn_add_dhcpopts($settings, $conf);
923 8dc3ef67 Scott Ullrich
924 d799787e Matthew Grooms
	if ($settings['gwredir'])
925
		$conf .= "push \"redirect-gateway def1\"\n";
926 6d031071 Martin Fuchs
927 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
928 8dc3ef67 Scott Ullrich
929 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
930
	chown($fpath, 'nobody');
931
	chgrp($fpath, 'nobody');
932
}
933 8dc3ef67 Scott Ullrich
934 dc408939 Matthew Grooms
function openvpn_delete_csc(& $settings) {
935 add2e3f7 Scott Ullrich
	global $g, $config;
936 3c2e5528 Scott Ullrich
937 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
938 d799787e Matthew Grooms
	unlink_if_exists($fpath);
939 267ab13f Ermal Luçi
}
940 afb07cf1 Scott Ullrich
941 24012690 Scott Ullrich
// Resync the configuration and restart the VPN
942 fc05822b jim-p
function openvpn_resync($mode, $settings) {
943 dc408939 Matthew Grooms
	openvpn_reconfigure($mode, $settings);
944
	openvpn_restart($mode, $settings);
945 afb07cf1 Scott Ullrich
}
946
947 add2e3f7 Scott Ullrich
// Resync and restart all VPNs
948 c7f60193 Ermal
function openvpn_resync_all($interface = "") {
949 d799787e Matthew Grooms
	global $g, $config;
950 267ab13f Ermal Luçi
951 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
952
		return;
953 a8f538a8 jim-p
	openvpn_create_dirs();
954 3cb54b54 Matthew Grooms
955 34bc1324 Matthew Grooms
	if (!is_array($config['openvpn']))
956
		$config['openvpn'] = array();
957
958 15b414e6 Matthew Grooms
/*
959 34bc1324 Matthew Grooms
	if (!$config['openvpn']['dh-parameters']) {
960
		echo "Configuring OpenVPN Parameters ...\n";
961 035e4289 Matthew Grooms
		$dh_parameters = openvpn_create_dhparams(1024);
962 34bc1324 Matthew Grooms
		$dh_parameters = base64_encode($dh_parameters);
963
		$config['openvpn']['dh-parameters'] = $dh_parameters;
964 c67dd94e Bill Marquette
		write_config("OpenVPN DH parameters");
965 34bc1324 Matthew Grooms
	}
966
967
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
968
	if (!file_exists($path_ovdh)) {
969
		$dh_parameters = $config['openvpn']['dh-parameters'];
970
		$dh_parameters = base64_decode($dh_parameters);
971
		file_put_contents($path_ovdh, $dh_parameters);
972
	}
973 15b414e6 Matthew Grooms
*/
974 739c9efd Ermal
	if ($interface <> "")
975 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances for interface " . convert_friendly_interface_to_friendly_descr($interface) . ".");
976 739c9efd Ermal
	else
977 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances."); 
978 34bc1324 Matthew Grooms
979 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-server'])) {
980
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
981 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
982 c7f60193 Ermal
				continue;
983 dc408939 Matthew Grooms
			openvpn_resync('server', $settings);
984 c7f60193 Ermal
		}
985
	}
986 5b237745 Scott Ullrich
987 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-client'])) {
988
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
989 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
990 c7f60193 Ermal
				continue;
991 dc408939 Matthew Grooms
			openvpn_resync('client', $settings);
992 c7f60193 Ermal
		}
993
	}
994 afb07cf1 Scott Ullrich
995 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-csc']))
996 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
997
			openvpn_resync_csc($settings);
998 afb07cf1 Scott Ullrich
999 5b237745 Scott Ullrich
}
1000 702a4702 Scott Ullrich
1001 99cc103b Phil Davis
// Resync and restart all VPNs using a gateway group.
1002
function openvpn_resync_gwgroup($gwgroupname = "") {
1003
	global $g, $config;
1004
1005
	if ($gwgroupname <> "") {
1006
		if (is_array($config['openvpn']['openvpn-server'])) {
1007
			foreach ($config['openvpn']['openvpn-server'] as & $settings) {
1008
				if ($gwgroupname == $settings['interface']) {
1009
					log_error("Resyncing OpenVPN for gateway group " . $gwgroupname . " server " . $settings["description"] . ".");
1010
					openvpn_resync('server', $settings);
1011
				}
1012
			}
1013
		}
1014
1015
		if (is_array($config['openvpn']['openvpn-client'])) {
1016
			foreach ($config['openvpn']['openvpn-client'] as & $settings) {
1017
				if ($gwgroupname == $settings['interface']) {
1018
					log_error("Resyncing OpenVPN for gateway group " . $gwgroupname . " client " . $settings["description"] . ".");
1019
					openvpn_resync('client', $settings);
1020
				}
1021
			}
1022
		}
1023
1024
		// Note: no need to resysnc Client Specific (csc) here, as changes to the OpenVPN real interface do not effect these.
1025
1026
	} else
1027
		log_error("openvpn_resync_gwgroup called with null gwgroup parameter."); 
1028
}
1029
1030 453d9c96 jim-p
function openvpn_get_active_servers($type="multipoint") {
1031 71ca2cb2 Ermal
	global $config, $g;
1032
1033 53663f57 jim-p
	$servers = array();
1034
	if (is_array($config['openvpn']['openvpn-server'])) {
1035
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
1036 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
1037
				continue;
1038
1039 53663f57 jim-p
			$prot = $settings['protocol'];
1040
			$port = $settings['local_port'];
1041
	
1042
			$server = array();
1043 95305736 jim-p
			$server['port'] = ($settings['local_port']) ? $settings['local_port'] : 1194;
1044 41be629f jim-p
			$server['mode'] = $settings['mode'];
1045 53663f57 jim-p
			if ($settings['description'])
1046
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
1047
			else
1048
				$server['name'] = "Server {$prot}:{$port}";
1049
			$server['conns'] = array();
1050 2eaa97b9 jim-p
			$server['vpnid'] = $settings['vpnid'];
1051
			$server['mgmt'] = "server{$server['vpnid']}";
1052
			$socket = "unix://{$g['varetc_path']}/openvpn/{$server['mgmt']}.sock";
1053 453d9c96 jim-p
			list($tn, $sm) = explode('/', $settings['tunnel_network']);
1054
1055
			if ((($server['mode'] == "p2p_shared_key") || ($sm >= 30) ) && ($type == "p2p"))
1056 95305736 jim-p
				$servers[] = openvpn_get_client_status($server, $socket);
1057 453d9c96 jim-p
			elseif (($server['mode'] != "p2p_shared_key") && ($type == "multipoint") && ($sm < 30))
1058 95305736 jim-p
				$servers[] = openvpn_get_server_status($server, $socket);
1059 453d9c96 jim-p
1060 95305736 jim-p
		}
1061
	}
1062
	return $servers;
1063
}
1064 b0140675 Ermal
1065 95305736 jim-p
function openvpn_get_server_status($server, $socket) {
1066
	$errval;
1067
	$errstr;
1068
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
1069
	if ($fp) {
1070
		stream_set_timeout($fp, 1);
1071
1072
		/* send our status request */
1073
		fputs($fp, "status 2\n");
1074
1075
		/* recv all response lines */
1076
		while (!feof($fp)) {
1077
1078
			/* read the next line */
1079
			$line = fgets($fp, 1024);
1080
1081
			$info = stream_get_meta_data($fp);
1082
			if ($info['timed_out'])
1083
				break;
1084
1085
			/* parse header list line */
1086
			if (strstr($line, "HEADER"))
1087
				continue;
1088
1089
			/* parse end of output line */
1090
			if (strstr($line, "END") || strstr($line, "ERROR"))
1091
				break;
1092
1093
			/* parse client list line */
1094
			if (strstr($line, "CLIENT_LIST")) {
1095
				$list = explode(",", $line);
1096 53663f57 jim-p
				$conn = array();
1097 95305736 jim-p
				$conn['common_name'] = $list[1];
1098
				$conn['remote_host'] = $list[2];
1099
				$conn['virtual_addr'] = $list[3];
1100
				$conn['bytes_recv'] = $list[4];
1101
				$conn['bytes_sent'] = $list[5];
1102
				$conn['connect_time'] = $list[6];
1103 53663f57 jim-p
				$server['conns'][] = $conn;
1104
			}
1105 ec970b50 jim-p
			/* parse routing table lines */
1106
			if (strstr($line, "ROUTING_TABLE")) {
1107
				$list = explode(",", $line);
1108
				$conn = array();
1109
				$conn['virtual_addr'] = $list[1];
1110
				$conn['common_name'] = $list[2];
1111
				$conn['remote_host'] = $list[3];
1112
				$conn['last_time'] = $list[4];
1113
				$server['routes'][] = $conn;
1114
			}
1115 53663f57 jim-p
		}
1116 95305736 jim-p
1117
		/* cleanup */
1118
		fclose($fp);
1119
	} else {
1120
		$conn = array();
1121
		$conn['common_name'] = "[error]";
1122 2eaa97b9 jim-p
		$conn['remote_host'] = "Unable to contact daemon";
1123
		$conn['virtual_addr'] = "Service not running?";
1124 95305736 jim-p
		$conn['bytes_recv'] = 0;
1125
		$conn['bytes_sent'] = 0;
1126
		$conn['connect_time'] = 0;
1127
		$server['conns'][] = $conn;
1128 53663f57 jim-p
	}
1129 95305736 jim-p
	return $server;
1130 53663f57 jim-p
}
1131
1132
function openvpn_get_active_clients() {
1133 71ca2cb2 Ermal
	global $config, $g;
1134
1135 53663f57 jim-p
	$clients = array();
1136
	if (is_array($config['openvpn']['openvpn-client'])) {
1137
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
1138
	
1139 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
1140
				continue;
1141
1142 53663f57 jim-p
			$prot = $settings['protocol'];
1143 95305736 jim-p
			$port = ($settings['local_port']) ? ":{$settings['local_port']}" : "";
1144 53663f57 jim-p
	
1145
			$client = array();
1146
			$client['port'] = $settings['local_port'];
1147
			if ($settings['description'])
1148 95305736 jim-p
				$client['name'] = "{$settings['description']} {$prot}{$port}";
1149 53663f57 jim-p
			else
1150 95305736 jim-p
				$client['name'] = "Client {$prot}{$port}";
1151 53663f57 jim-p
	
1152 2eaa97b9 jim-p
			$client['vpnid'] = $settings['vpnid'];
1153
			$client['mgmt'] = "client{$client['vpnid']}";
1154
			$socket = "unix://{$g['varetc_path']}/openvpn/{$client['mgmt']}.sock";
1155 53663f57 jim-p
			$client['status']="down";
1156 95305736 jim-p
1157
			$clients[] = openvpn_get_client_status($client, $socket);
1158
		}
1159
	}
1160
	return $clients;
1161
}
1162
1163
function openvpn_get_client_status($client, $socket) {
1164
	$errval;
1165
	$errstr;
1166
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
1167
	if ($fp) {
1168
		stream_set_timeout($fp, 1);
1169
		/* send our status request */
1170
		fputs($fp, "state 1\n");
1171
1172
		/* recv all response lines */
1173
		while (!feof($fp)) {
1174
			/* read the next line */
1175
			$line = fgets($fp, 1024);
1176
1177
			$info = stream_get_meta_data($fp);
1178
			if ($info['timed_out'])
1179
				break;
1180
1181
			/* Get the client state */
1182
			if (strstr($line,"CONNECTED")) {
1183
				$client['status']="up";
1184
				$list = explode(",", $line);
1185
1186
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1187
				$client['virtual_addr']  = $list[3];
1188
				$client['remote_host'] = $list[4];
1189
			}
1190 453d9c96 jim-p
			if (strstr($line,"CONNECTING")) {
1191
				$client['status']="connecting";
1192
			}
1193
			if (strstr($line,"ASSIGN_IP")) {
1194
				$client['status']="waiting";
1195
				$list = explode(",", $line);
1196
1197
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1198
				$client['virtual_addr']  = $list[3];
1199
			}
1200
			if (strstr($line,"RECONNECTING")) {
1201
				$client['status']="reconnecting";
1202
				$list = explode(",", $line);
1203
1204
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1205
				$client['status'] .= "; " . $list[2];
1206
			}
1207 95305736 jim-p
			/* parse end of output line */
1208
			if (strstr($line, "END") || strstr($line, "ERROR"))
1209
				break;
1210
		}
1211
1212
		/* If up, get read/write stats */
1213
		if (strcmp($client['status'], "up") == 0) {
1214
			fputs($fp, "status 2\n");
1215
			/* recv all response lines */
1216
			while (!feof($fp)) {
1217
				/* read the next line */
1218
				$line = fgets($fp, 1024);
1219
1220
				$info = stream_get_meta_data($fp);
1221
				if ($info['timed_out'])
1222
					break;
1223
1224
				if (strstr($line,"TCP/UDP read bytes")) {
1225
					$list = explode(",", $line);
1226
					$client['bytes_recv'] = $list[1];
1227 53663f57 jim-p
				}
1228 95305736 jim-p
1229
				if (strstr($line,"TCP/UDP write bytes")) {
1230
					$list = explode(",", $line);
1231
					$client['bytes_sent'] = $list[1];
1232 53663f57 jim-p
				}
1233 95305736 jim-p
1234
				/* parse end of output line */
1235
				if (strstr($line, "END"))
1236
					break;
1237 53663f57 jim-p
			}
1238
		}
1239 95305736 jim-p
1240
		fclose($fp);
1241
1242
	} else {
1243
		$DisplayNote=true;
1244 2eaa97b9 jim-p
		$client['remote_host'] = "Unable to contact daemon";
1245
		$client['virtual_addr'] = "Service not running?";
1246 95305736 jim-p
		$client['bytes_recv'] = 0;
1247
		$client['bytes_sent'] = 0;
1248
		$client['connect_time'] = 0;
1249 53663f57 jim-p
	}
1250 95305736 jim-p
	return $client;
1251 53663f57 jim-p
}
1252 8e022a76 jim-p
1253
function openvpn_refresh_crls() {
1254
	global $g, $config;
1255
1256 a8f538a8 jim-p
	openvpn_create_dirs();
1257 8e022a76 jim-p
1258
	if (is_array($config['openvpn']['openvpn-server'])) {
1259
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1260
			if (empty($settings))
1261
				continue;
1262
			if (isset($settings['disable']))
1263
				continue;
1264
			// Write the settings for the keys
1265
			switch($settings['mode']) {
1266
				case 'p2p_tls':
1267
				case 'server_tls':
1268
				case 'server_tls_user':
1269
				case 'server_user':
1270
					if (!empty($settings['crlref'])) {
1271
						$crl = lookup_crl($settings['crlref']);
1272 728003c8 jim-p
						crl_update($crl);
1273 8e022a76 jim-p
						$fpath = $g['varetc_path']."/openvpn/server{$settings['vpnid']}.crl-verify";
1274
						file_put_contents($fpath, base64_decode($crl['text']));
1275
						@chmod($fpath, 0644);
1276
					}
1277
					break;
1278
			}
1279
		}
1280
	}
1281
}
1282
1283 a8f538a8 jim-p
function openvpn_create_dirs() {
1284
	global $g;
1285
	if (!is_dir("{$g['varetc_path']}/openvpn"))
1286
		safe_mkdir("{$g['varetc_path']}/openvpn", 0750);
1287
	if (!is_dir("{$g['varetc_path']}/openvpn-csc"))
1288
		safe_mkdir("{$g['varetc_path']}/openvpn-csc", 0750);
1289
}
1290
1291 91c44185 jim-p
function openvpn_get_interface_ip($ip, $mask) {
1292
	$baselong = ip2long32($ip) & ip2long($mask);
1293
	$ip1 = long2ip32($baselong + 1);
1294
	$ip2 = long2ip32($baselong + 2);
1295
	return array($ip1, $ip2);
1296
}
1297
1298
function openvpn_get_interface_ipv6($ipv6, $prefix) {
1299
	$basev6 = gen_subnetv6($ipv6, $prefix);
1300
	// Is there a better way to do this math?
1301
	$ipv6_arr = explode(':', $basev6);
1302
	$last = hexdec(array_pop($ipv6_arr));
1303 fe9c774d Phil Davis
	$ipv6_1 = Net_IPv6::compress(Net_IPv6::uncompress(implode(':', $ipv6_arr) . ':' . dechex($last + 1)));
1304
	$ipv6_2 = Net_IPv6::compress(Net_IPv6::uncompress(implode(':', $ipv6_arr) . ':' . dechex($last + 2)));
1305 91c44185 jim-p
	return array($ipv6_1, $ipv6_2);
1306
}
1307
1308
function openvpn_clear_route($mode, $settings) {
1309
	if (empty($settings['tunnel_network']))
1310
		return;
1311
	list($ip, $cidr) = explode('/', $settings['tunnel_network']);
1312
	$mask = gen_subnet_mask($cidr);
1313 6ca938cf jim-p
	$clear_route = false;
1314
1315 91c44185 jim-p
	switch($settings['mode']) {
1316 6ca938cf jim-p
		case 'shared_key':
1317
			$clear_route = true;
1318
			break;
1319 91c44185 jim-p
		case 'p2p_tls':
1320
		case 'p2p_shared_key':
1321 6d0b9fe9 jim-p
			if ($cidr == 30)
1322 6ca938cf jim-p
				$clear_route = true;
1323 91c44185 jim-p
			break;
1324
	}
1325 6ca938cf jim-p
1326 6d0b9fe9 jim-p
	if ($clear_route && !empty($ip) && !empty($mask)) {
1327 6ca938cf jim-p
		list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
1328
		$ip_to_clear = ($mode == "server") ? $ip1 : $ip2;
1329 615d7f0a Ermal
		/* XXX: Family for route? */
1330 6ca938cf jim-p
		mwexec("/sbin/route -q delete {$ip_to_clear}");
1331
	}
1332 91c44185 jim-p
}
1333
1334 5c427ce7 jim-p
function openvpn_gen_routes($value, $ipproto = "ipv4", $push = false, $iroute = false) {
1335 a28d40cb jim-p
	$routes = "";
1336
	if (empty($value))
1337
		return "";
1338
	$networks = explode(',', $value);
1339
1340
	foreach ($networks as $network) {
1341
		if ($ipproto == "ipv4")
1342 5c427ce7 jim-p
			$route = openvpn_gen_route_ipv4($network, $iroute);
1343 a28d40cb jim-p
		else
1344 5c427ce7 jim-p
			$route = openvpn_gen_route_ipv6($network, $iroute);
1345 a28d40cb jim-p
1346
		if ($push)
1347
			$routes .= "push \"{$route}\"\n";
1348
		else
1349
			$routes .= "{$route}\n";
1350
	}
1351
	return $routes;
1352
}
1353
1354 5c427ce7 jim-p
function openvpn_gen_route_ipv4($network, $iroute = false) {
1355
	$i = ($iroute) ? "i" : "";
1356 a28d40cb jim-p
	list($ip, $mask) = explode('/', trim($network));
1357
	$mask = gen_subnet_mask($mask);
1358 5c427ce7 jim-p
	return "{$i}route $ip $mask";
1359 a28d40cb jim-p
}
1360
1361 5c427ce7 jim-p
function openvpn_gen_route_ipv6($network, $iroute = false) {
1362
	$i = ($iroute) ? "i" : "";
1363 a28d40cb jim-p
	list($ipv6, $prefix) = explode('/', trim($network));
1364
	if (empty($prefix))
1365
		$prefix = "128";
1366 5c427ce7 jim-p
	return "{$i}route-ipv6 ${ipv6}/${prefix}";
1367 a28d40cb jim-p
}
1368
1369 699125b1 jim-p
function openvpn_get_settings($mode, $vpnid) {
1370
	global $config;
1371
1372
	if (is_array($config['openvpn']['openvpn-server'])) {
1373
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1374
			if (isset($settings['disable']))
1375
				continue;
1376
1377
			if ($vpnid != 0 && $vpnid == $settings['vpnid'])
1378
				return $settings;
1379
		}
1380
	}
1381
1382
	if (is_array($config['openvpn']['openvpn-client'])) {
1383
		foreach ($config['openvpn']['openvpn-client'] as $settings) {
1384
			if (isset($settings['disable']))
1385
				continue;
1386
1387
			if ($vpnid != 0 && $vpnid == $settings['vpnid'])
1388
				return $settings;
1389
		}
1390
	}
1391
1392
	return array();
1393
}
1394
1395
function openvpn_restart_by_vpnid($mode, $vpnid) {
1396
	$settings = openvpn_get_settings($mode, $vpnid);
1397
	openvpn_restart($mode, $settings);
1398
}
1399
1400 756720e2 Pierre POMES
?>