Project

General

Profile

Download (41.8 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 2da48592 jim-p
			if (($mode == 'client') && empty($settings['certref']))
597
				$cert = "";
598
			else {
599
				$cert = lookup_cert($settings['certref']);
600
				/* XXX: Seems not used at all! */
601
				$servercn = urlencode(cert_get_cn($cert['crt']));
602
				$conf .= "tls-verify \"/usr/local/sbin/ovpn_auth_verify tls '{$servercn}' {$settings['cert_depth']}\"\n";
603
			}
604 98963f27 jim-p
		}
605 8dc3ef67 Scott Ullrich
606 63084885 Matthew Grooms
		// The local port to listen on
607 d799787e Matthew Grooms
		$conf .= "lport {$settings['local_port']}\n";
608 c0cf27aa Scott Ullrich
609 63084885 Matthew Grooms
		// The management port to listen on
610 71ca2cb2 Ermal
		// Use unix socket to overcome the problem on any type of server
611
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
612
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
613 63084885 Matthew Grooms
614 3c11bd3c Matthew Grooms
		if ($settings['maxclients'])
615 d799787e Matthew Grooms
			$conf .= "max-clients {$settings['maxclients']}\n";
616
617 3c11bd3c Matthew Grooms
		// Can we push routes
618
		if ($settings['local_network']) {
619 a28d40cb jim-p
			$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
620 3c11bd3c Matthew Grooms
		}
621 787de45a Seth Mos
		if ($settings['local_networkv6']) {
622 a28d40cb jim-p
			$conf .= openvpn_gen_routes($settings['local_networkv6'], "ipv6", true);
623 787de45a Seth Mos
		}
624 3c11bd3c Matthew Grooms
625
		switch($settings['mode']) {
626
			case 'server_tls':
627
			case 'server_user':
628
			case 'server_tls_user':
629 5d8cd81a jim-p
				// Configure client dhcp options
630 3c11bd3c Matthew Grooms
				openvpn_add_dhcpopts($settings, $conf);
631 5d8cd81a jim-p
				if ($settings['client2client'])
632
					$conf .= "client-to-client\n";
633 3c11bd3c Matthew Grooms
				break;
634
		}
635 bca35cff jim-p
		if (isset($settings['duplicate_cn']))
636
			$conf .= "duplicate-cn\n";
637 d799787e Matthew Grooms
	}
638
639 3c11bd3c Matthew Grooms
	// client specific settings
640 d799787e Matthew Grooms
641 3c11bd3c Matthew Grooms
	if ($mode == 'client') {
642 d799787e Matthew Grooms
643 3c11bd3c Matthew Grooms
		// configure p2p mode
644
		switch($settings['mode']) {
645
			case 'p2p_tls':
646
				$conf .= "tls-client\n";
647
			case 'shared_key':
648
				$conf .= "client\n";
649
				break;
650
		}
651 d799787e Matthew Grooms
652 e3924384 jim-p
		// If there is no bind option at all (ip and/or port), add "nobind" directive
653
		//  Otherwise, use the local port if defined, failing that, use lport 0 to 
654
		//  ensure a random source port.
655
		if ((empty($iface_ip)) && (!$settings['local_port']))
656
			$conf .= "nobind\n";
657
		elseif ($settings['local_port'])
658
			$conf .= "lport {$settings['local_port']}\n";
659
		else
660
			$conf .= "lport 0\n";
661 5708241f jim-p
662 4b887ef4 jim-p
		// Use unix socket to overcome the problem on any type of server
663
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
664 48a458d2 pierrepomes
665 3c11bd3c Matthew Grooms
		// The remote server
666
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
667
668 d799787e Matthew Grooms
		if (!empty($settings['use_shaper']))
669
			$conf .= "shaper {$settings['use_shaper']}\n";
670 ee506044 Scott Ullrich
671 d799787e Matthew Grooms
		if (!empty($settings['tunnel_network'])) {
672
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
673 8dc3ef67 Scott Ullrich
			$mask = gen_subnet_mask($mask);
674 91c44185 jim-p
			list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
675 459e9333 jim-p
			if ($settings['dev_mode'] == 'tun')
676
				$conf .= "ifconfig {$ip2} {$ip1}\n";
677
			else
678
				$conf .= "ifconfig {$ip2} {$mask}\n";
679 8dc3ef67 Scott Ullrich
		}
680 d799787e Matthew Grooms
681 a0e3ee98 jim-p
		if (!empty($settings['tunnel_networkv6'])) {
682
			list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
683 91c44185 jim-p
			list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
684 a0e3ee98 jim-p
			if ($settings['dev_mode'] == 'tun')
685
				$conf .= "ifconfig-ipv6 {$ipv6_2} {$ipv6_1}\n";
686
			else
687 60f501ec Phil Davis
				$conf .= "ifconfig-ipv6 {$ipv6_2} {$prefix}\n";
688 a0e3ee98 jim-p
		}
689
690 5f242576 PiBa-NL
		if ($settings['auth_user'] && $settings['auth_pass']) {
691
			$up_file = "{$g['varetc_path']}/openvpn/{$mode_id}.up";
692
			$conf .= "auth-user-pass {$up_file}\n";
693
			$userpass = "{$settings['auth_user']}\n";
694
			$userpass .= "{$settings['auth_pass']}\n";
695
			file_put_contents($up_file, $userpass);
696
		}
697
		
698 762a24a3 Ermal Lu?i
		if ($settings['proxy_addr']) {
699
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
700
			if ($settings['proxy_authtype'] != "none") {
701
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
702
				$proxypas = "{$settings['proxy_user']}\n";
703
				$proxypas .= "{$settings['proxy_passwd']}\n";
704
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
705
			}
706
			$conf .= " \n";
707
		}
708 8dc3ef67 Scott Ullrich
	}
709
710 17c98ba9 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_network'], "", true, "ipv4") === FALSE)) {
712 a28d40cb jim-p
		$conf .= openvpn_gen_routes($settings['remote_network'], "ipv4", false);
713 8dc3ef67 Scott Ullrich
	}
714 4856df9b jim-p
	// Add a remote network route if set, and only for p2p modes.
715 54285411 jim-p
	if ((substr($settings['mode'], 0, 3) == "p2p") && (openvpn_validate_cidr($settings['remote_networkv6'], "", true, "ipv6") === FALSE)) {
716 a28d40cb jim-p
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false);
717 4856df9b jim-p
	}
718 afb07cf1 Scott Ullrich
719 d799787e Matthew Grooms
	// Write the settings for the keys
720 3c11bd3c Matthew Grooms
	switch($settings['mode']) {
721
		case 'p2p_shared_key':
722
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
723
			break;
724
		case 'p2p_tls':
725
		case 'server_tls':
726
		case 'server_tls_user':
727 e62e2f8b Ermal Lu?i
		case 'server_user':
728 3c11bd3c Matthew Grooms
			$ca = lookup_ca($settings['caref']);
729
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
730 2da48592 jim-p
731
			if (!empty($settings['certref'])) {
732
				$cert = lookup_cert($settings['certref']);
733
				openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
734
				openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
735
			}
736 3c11bd3c Matthew Grooms
			if ($mode == 'server')
737 fe787fc7 Matthew Grooms
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
738 6db02381 jim-p
			if (!empty($settings['crlref'])) {
739
				$crl = lookup_crl($settings['crlref']);
740 cfcc6994 jim-p
				crl_update($crl);
741 6db02381 jim-p
				openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify");
742
			}
743 db746ce2 Ermal Lu?i
			if ($settings['tls']) {
744 756720e2 Pierre POMES
				if ($mode == "server") 
745 db746ce2 Ermal Lu?i
					$tlsopt = 0;
746
				else
747
					$tlsopt = 1;
748
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
749
			}
750 3c11bd3c Matthew Grooms
			break;
751 8dc3ef67 Scott Ullrich
	}
752
753 edba1982 jim-p
	if (!empty($settings['compression']))
754
		$conf .= "comp-lzo {$settings['compression']}\n";
755 d799787e Matthew Grooms
756
	if ($settings['passtos'])
757
		$conf .= "passtos\n";
758
759
	if ($settings['resolve_retry'])
760
		$conf .= "resolv-retry infinite\n";
761
762
	if ($settings['dynamic_ip']) {
763
		$conf .= "persist-remote-ip\n";
764
		$conf .= "float\n";
765 8dc3ef67 Scott Ullrich
	}
766 afb07cf1 Scott Ullrich
767 ee55ce7d jim-p
	if ($settings['topology_subnet']) {
768
		$conf .= "topology subnet\n";
769
	}
770
771 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
772
773 a8f538a8 jim-p
	openvpn_create_dirs();
774 938fc5b0 Ermal
	$fpath = "{$g['varetc_path']}/openvpn/{$mode_id}.conf";
775 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
776 938fc5b0 Ermal
	unset($conf);
777 be00850b Phil Davis
	$fpath = "{$g['varetc_path']}/openvpn/{$mode_id}.interface";
778
	file_put_contents($fpath, $interface);
779 f9ac3784 Ermal Lu?i
	//chown($fpath, 'nobody');
780
	//chgrp($fpath, 'nobody');
781 6f27412f Ermal Lu?i
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
782 be00850b Phil Davis
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.interface", 0600);
783 6f27412f Ermal Lu?i
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
784
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
785
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
786 d799787e Matthew Grooms
}
787
788 fc05822b jim-p
function openvpn_restart($mode, $settings) {
789 d799787e Matthew Grooms
	global $g, $config;
790
791
	$vpnid = $settings['vpnid'];
792
	$mode_id = $mode.$vpnid;
793
794 76369bfc Matthew Grooms
	/* kill the process if running */
795 705c8ec9 Matthew Grooms
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
796 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
797 705c8ec9 Matthew Grooms
798 76369bfc Matthew Grooms
		/* read the pid file */
799
		$pid = rtrim(file_get_contents($pfile));
800
		unlink($pfile);
801 705c8ec9 Matthew Grooms
802 76369bfc Matthew Grooms
		/* send a term signal to the process */
803
		posix_kill($pid, SIGTERM);
804
805
		/* wait until the process exits */
806
		while(posix_kill($pid, 0))
807
			usleep(250000);
808
	}
809 d799787e Matthew Grooms
810 a1cab2c7 Ermal
	if (isset($settings['disable']))
811 d799787e Matthew Grooms
		return;
812
813 260f267e jim-p
	/* Do not start a client if we are a CARP backup on this vip! */
814 0c21eb70 Ermal
	if (($mode == "client") && (strstr($settings['interface'], "_vip") && get_carp_interface_status($settings['interface']) == "BACKUP"))
815 9ea0cb90 jim-p
		return;
816 330ecea1 Shahid Sheikh
		
817
	/* Check if client is bound to a gateway group */    
818
	$a_groups = return_gateway_groups_array();
819
	if (is_array($a_groups[$settings['interface']])) {
820
	/* the interface is a gateway group. If a vip is defined and its a CARP backup then do not start */
821
		if (($a_groups[$settings['interface']][0]['vip'] <> "") && (get_carp_interface_status($a_groups[$settings['interface']][0]['vip']) == "BACKUP"))
822
			return;
823
	}
824 9ea0cb90 jim-p
825 705c8ec9 Matthew Grooms
	/* start the new process */
826 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
827 91c44185 jim-p
	openvpn_clear_route($mode, $settings);
828 873c1701 Renato Botelho
	mwexec_bg("/usr/local/sbin/openvpn --config " . escapeshellarg($fpath));
829 847cd48d Ermal
830
	if (!$g['booting'])
831
		send_event("filter reload");
832 afb07cf1 Scott Ullrich
}
833
834 dc408939 Matthew Grooms
function openvpn_delete($mode, & $settings) {
835 d799787e Matthew Grooms
	global $g, $config;
836
837
	$vpnid = $settings['vpnid'];
838
	$mode_id = $mode.$vpnid;
839
840 da601f8e PiBa-NL
	if (isset($settings['dev_mode']))
841
		$tunname = "{$settings['dev_mode']}{$vpnid}";
842
	else {  /* defaults to tun */
843
		$tunname = "tun{$vpnid}";
844
	}
845
846 095a95ae Matthew Grooms
	if ($mode == "server")
847
		$devname = "ovpns{$vpnid}";
848
	else
849
		$devname = "ovpnc{$vpnid}";
850 dc408939 Matthew Grooms
851 76369bfc Matthew Grooms
	/* kill the process if running */
852 dc408939 Matthew Grooms
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
853 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
854 dc408939 Matthew Grooms
855 76369bfc Matthew Grooms
		/* read the pid file */
856
		$pid = trim(file_get_contents($pfile));
857
		unlink($pfile);
858
859
		/* send a term signal to the process */
860
		posix_kill($pid, SIGTERM);
861
	}
862 705c8ec9 Matthew Grooms
863 095a95ae Matthew Grooms
	/* remove the device from the openvpn group */
864 873c1701 Renato Botelho
	mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " -group openvpn");
865 095a95ae Matthew Grooms
866 dc408939 Matthew Grooms
	/* restore the original adapter name */
867 873c1701 Renato Botelho
	mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " name " . escapeshellarg($tunname));
868 dc408939 Matthew Grooms
869
	/* remove the configuration files */
870 873c1701 Renato Botelho
	array_map('unlink', glob("{$g['varetc_path']}/openvpn/{$mode_id}.*"));
871 d799787e Matthew Grooms
}
872 afb07cf1 Scott Ullrich
873 de85521a jim-p
function openvpn_cleanup_csc($common_name) {
874
	global $g, $config;
875
	if (empty($common_name))
876
		return;
877
	$fpath = "{$g['varetc_path']}/openvpn-csc/" . basename($common_name);
878
	if (is_file($fpath))
879
		unlink_if_exists($fpath);
880
	return;
881
}
882
883 dc408939 Matthew Grooms
function openvpn_resync_csc(& $settings) {
884 8dc3ef67 Scott Ullrich
	global $g, $config;
885
886 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
887 8dc3ef67 Scott Ullrich
888 a1cab2c7 Ermal
	if (isset($settings['disable'])) {
889 d799787e Matthew Grooms
		unlink_if_exists($fpath);
890 c876662c Scott Ullrich
		return;
891
	}
892 a8f538a8 jim-p
	openvpn_create_dirs();
893 d799787e Matthew Grooms
894 8dc3ef67 Scott Ullrich
	$conf = '';
895 d799787e Matthew Grooms
	if ($settings['block'])
896
		$conf .= "disable\n";
897
898
	if ($settings['push_reset'])
899
		$conf .= "push-reset\n";
900
901
	if (!empty($settings['tunnel_network'])) {
902
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
903 96033063 Erik Fonnesbeck
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
904 298fe5ae jim-p
		$serverip = long2ip32($baselong + 1);
905
		$clientip = long2ip32($baselong + 2);
906
		/* Because this is being pushed, the order from the client's point of view. */
907 d9c96fb1 jim-p
		if ($settings['dev_mode'] != 'tap')
908
			$conf .= "ifconfig-push {$clientip} {$serverip}\n";
909 e052047d jim-p
		else
910
			$conf .= "ifconfig-push {$clientip} {$mask}\n";
911 8dc3ef67 Scott Ullrich
	}
912 6d031071 Martin Fuchs
913 5c427ce7 jim-p
	if ($settings['local_network']) {
914
		$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
915
	}
916
	if ($settings['local_networkv6']) {
917
		$conf .= openvpn_gen_routes($settings['local_networkv6'], "ipv6", true);
918
	}
919
920
	// Add a remote network iroute if set
921
	if (openvpn_validate_cidr($settings['remote_network'], "", true, "ipv4") === FALSE) {
922
		$conf .= openvpn_gen_routes($settings['remote_network'], "ipv4", false, true);
923
	}
924
	// Add a remote network iroute if set
925
	if (openvpn_validate_cidr($settings['remote_networkv6'], "", true, "ipv6") === FALSE) {
926
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false, true);
927
	}
928
929 d799787e Matthew Grooms
	openvpn_add_dhcpopts($settings, $conf);
930 8dc3ef67 Scott Ullrich
931 d799787e Matthew Grooms
	if ($settings['gwredir'])
932
		$conf .= "push \"redirect-gateway def1\"\n";
933 6d031071 Martin Fuchs
934 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
935 8dc3ef67 Scott Ullrich
936 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
937
	chown($fpath, 'nobody');
938
	chgrp($fpath, 'nobody');
939
}
940 8dc3ef67 Scott Ullrich
941 dc408939 Matthew Grooms
function openvpn_delete_csc(& $settings) {
942 add2e3f7 Scott Ullrich
	global $g, $config;
943 3c2e5528 Scott Ullrich
944 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
945 d799787e Matthew Grooms
	unlink_if_exists($fpath);
946 267ab13f Ermal Luçi
}
947 afb07cf1 Scott Ullrich
948 24012690 Scott Ullrich
// Resync the configuration and restart the VPN
949 fc05822b jim-p
function openvpn_resync($mode, $settings) {
950 dc408939 Matthew Grooms
	openvpn_reconfigure($mode, $settings);
951
	openvpn_restart($mode, $settings);
952 afb07cf1 Scott Ullrich
}
953
954 add2e3f7 Scott Ullrich
// Resync and restart all VPNs
955 c7f60193 Ermal
function openvpn_resync_all($interface = "") {
956 d799787e Matthew Grooms
	global $g, $config;
957 267ab13f Ermal Luçi
958 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
959
		return;
960 a8f538a8 jim-p
	openvpn_create_dirs();
961 3cb54b54 Matthew Grooms
962 34bc1324 Matthew Grooms
	if (!is_array($config['openvpn']))
963
		$config['openvpn'] = array();
964
965 15b414e6 Matthew Grooms
/*
966 34bc1324 Matthew Grooms
	if (!$config['openvpn']['dh-parameters']) {
967
		echo "Configuring OpenVPN Parameters ...\n";
968 035e4289 Matthew Grooms
		$dh_parameters = openvpn_create_dhparams(1024);
969 34bc1324 Matthew Grooms
		$dh_parameters = base64_encode($dh_parameters);
970
		$config['openvpn']['dh-parameters'] = $dh_parameters;
971 c67dd94e Bill Marquette
		write_config("OpenVPN DH parameters");
972 34bc1324 Matthew Grooms
	}
973
974
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
975
	if (!file_exists($path_ovdh)) {
976
		$dh_parameters = $config['openvpn']['dh-parameters'];
977
		$dh_parameters = base64_decode($dh_parameters);
978
		file_put_contents($path_ovdh, $dh_parameters);
979
	}
980 15b414e6 Matthew Grooms
*/
981 739c9efd Ermal
	if ($interface <> "")
982 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances for interface " . convert_friendly_interface_to_friendly_descr($interface) . ".");
983 739c9efd Ermal
	else
984 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances."); 
985 34bc1324 Matthew Grooms
986 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-server'])) {
987
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
988 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
989 c7f60193 Ermal
				continue;
990 dc408939 Matthew Grooms
			openvpn_resync('server', $settings);
991 c7f60193 Ermal
		}
992
	}
993 5b237745 Scott Ullrich
994 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-client'])) {
995
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
996 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
997 c7f60193 Ermal
				continue;
998 dc408939 Matthew Grooms
			openvpn_resync('client', $settings);
999 c7f60193 Ermal
		}
1000
	}
1001 afb07cf1 Scott Ullrich
1002 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-csc']))
1003 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
1004
			openvpn_resync_csc($settings);
1005 afb07cf1 Scott Ullrich
1006 5b237745 Scott Ullrich
}
1007 702a4702 Scott Ullrich
1008 99cc103b Phil Davis
// Resync and restart all VPNs using a gateway group.
1009
function openvpn_resync_gwgroup($gwgroupname = "") {
1010
	global $g, $config;
1011
1012
	if ($gwgroupname <> "") {
1013
		if (is_array($config['openvpn']['openvpn-server'])) {
1014
			foreach ($config['openvpn']['openvpn-server'] as & $settings) {
1015
				if ($gwgroupname == $settings['interface']) {
1016
					log_error("Resyncing OpenVPN for gateway group " . $gwgroupname . " server " . $settings["description"] . ".");
1017
					openvpn_resync('server', $settings);
1018
				}
1019
			}
1020
		}
1021
1022
		if (is_array($config['openvpn']['openvpn-client'])) {
1023
			foreach ($config['openvpn']['openvpn-client'] as & $settings) {
1024
				if ($gwgroupname == $settings['interface']) {
1025
					log_error("Resyncing OpenVPN for gateway group " . $gwgroupname . " client " . $settings["description"] . ".");
1026
					openvpn_resync('client', $settings);
1027
				}
1028
			}
1029
		}
1030
1031
		// Note: no need to resysnc Client Specific (csc) here, as changes to the OpenVPN real interface do not effect these.
1032
1033
	} else
1034
		log_error("openvpn_resync_gwgroup called with null gwgroup parameter."); 
1035
}
1036
1037 453d9c96 jim-p
function openvpn_get_active_servers($type="multipoint") {
1038 71ca2cb2 Ermal
	global $config, $g;
1039
1040 53663f57 jim-p
	$servers = array();
1041
	if (is_array($config['openvpn']['openvpn-server'])) {
1042
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
1043 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
1044
				continue;
1045
1046 53663f57 jim-p
			$prot = $settings['protocol'];
1047
			$port = $settings['local_port'];
1048
	
1049
			$server = array();
1050 95305736 jim-p
			$server['port'] = ($settings['local_port']) ? $settings['local_port'] : 1194;
1051 41be629f jim-p
			$server['mode'] = $settings['mode'];
1052 53663f57 jim-p
			if ($settings['description'])
1053
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
1054
			else
1055
				$server['name'] = "Server {$prot}:{$port}";
1056
			$server['conns'] = array();
1057 2eaa97b9 jim-p
			$server['vpnid'] = $settings['vpnid'];
1058
			$server['mgmt'] = "server{$server['vpnid']}";
1059
			$socket = "unix://{$g['varetc_path']}/openvpn/{$server['mgmt']}.sock";
1060 453d9c96 jim-p
			list($tn, $sm) = explode('/', $settings['tunnel_network']);
1061
1062
			if ((($server['mode'] == "p2p_shared_key") || ($sm >= 30) ) && ($type == "p2p"))
1063 95305736 jim-p
				$servers[] = openvpn_get_client_status($server, $socket);
1064 453d9c96 jim-p
			elseif (($server['mode'] != "p2p_shared_key") && ($type == "multipoint") && ($sm < 30))
1065 95305736 jim-p
				$servers[] = openvpn_get_server_status($server, $socket);
1066 453d9c96 jim-p
1067 95305736 jim-p
		}
1068
	}
1069
	return $servers;
1070
}
1071 b0140675 Ermal
1072 95305736 jim-p
function openvpn_get_server_status($server, $socket) {
1073
	$errval;
1074
	$errstr;
1075
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
1076
	if ($fp) {
1077
		stream_set_timeout($fp, 1);
1078
1079
		/* send our status request */
1080
		fputs($fp, "status 2\n");
1081
1082
		/* recv all response lines */
1083
		while (!feof($fp)) {
1084
1085
			/* read the next line */
1086
			$line = fgets($fp, 1024);
1087
1088
			$info = stream_get_meta_data($fp);
1089
			if ($info['timed_out'])
1090
				break;
1091
1092
			/* parse header list line */
1093
			if (strstr($line, "HEADER"))
1094
				continue;
1095
1096
			/* parse end of output line */
1097
			if (strstr($line, "END") || strstr($line, "ERROR"))
1098
				break;
1099
1100
			/* parse client list line */
1101
			if (strstr($line, "CLIENT_LIST")) {
1102
				$list = explode(",", $line);
1103 53663f57 jim-p
				$conn = array();
1104 95305736 jim-p
				$conn['common_name'] = $list[1];
1105
				$conn['remote_host'] = $list[2];
1106
				$conn['virtual_addr'] = $list[3];
1107
				$conn['bytes_recv'] = $list[4];
1108
				$conn['bytes_sent'] = $list[5];
1109
				$conn['connect_time'] = $list[6];
1110 53663f57 jim-p
				$server['conns'][] = $conn;
1111
			}
1112 ec970b50 jim-p
			/* parse routing table lines */
1113
			if (strstr($line, "ROUTING_TABLE")) {
1114
				$list = explode(",", $line);
1115
				$conn = array();
1116
				$conn['virtual_addr'] = $list[1];
1117
				$conn['common_name'] = $list[2];
1118
				$conn['remote_host'] = $list[3];
1119
				$conn['last_time'] = $list[4];
1120
				$server['routes'][] = $conn;
1121
			}
1122 53663f57 jim-p
		}
1123 95305736 jim-p
1124
		/* cleanup */
1125
		fclose($fp);
1126
	} else {
1127
		$conn = array();
1128
		$conn['common_name'] = "[error]";
1129 2eaa97b9 jim-p
		$conn['remote_host'] = "Unable to contact daemon";
1130
		$conn['virtual_addr'] = "Service not running?";
1131 95305736 jim-p
		$conn['bytes_recv'] = 0;
1132
		$conn['bytes_sent'] = 0;
1133
		$conn['connect_time'] = 0;
1134
		$server['conns'][] = $conn;
1135 53663f57 jim-p
	}
1136 95305736 jim-p
	return $server;
1137 53663f57 jim-p
}
1138
1139
function openvpn_get_active_clients() {
1140 71ca2cb2 Ermal
	global $config, $g;
1141
1142 53663f57 jim-p
	$clients = array();
1143
	if (is_array($config['openvpn']['openvpn-client'])) {
1144
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
1145
	
1146 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
1147
				continue;
1148
1149 53663f57 jim-p
			$prot = $settings['protocol'];
1150 95305736 jim-p
			$port = ($settings['local_port']) ? ":{$settings['local_port']}" : "";
1151 53663f57 jim-p
	
1152
			$client = array();
1153
			$client['port'] = $settings['local_port'];
1154
			if ($settings['description'])
1155 95305736 jim-p
				$client['name'] = "{$settings['description']} {$prot}{$port}";
1156 53663f57 jim-p
			else
1157 95305736 jim-p
				$client['name'] = "Client {$prot}{$port}";
1158 53663f57 jim-p
	
1159 2eaa97b9 jim-p
			$client['vpnid'] = $settings['vpnid'];
1160
			$client['mgmt'] = "client{$client['vpnid']}";
1161
			$socket = "unix://{$g['varetc_path']}/openvpn/{$client['mgmt']}.sock";
1162 53663f57 jim-p
			$client['status']="down";
1163 95305736 jim-p
1164
			$clients[] = openvpn_get_client_status($client, $socket);
1165
		}
1166
	}
1167
	return $clients;
1168
}
1169
1170
function openvpn_get_client_status($client, $socket) {
1171
	$errval;
1172
	$errstr;
1173
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
1174
	if ($fp) {
1175
		stream_set_timeout($fp, 1);
1176
		/* send our status request */
1177
		fputs($fp, "state 1\n");
1178
1179
		/* recv all response lines */
1180
		while (!feof($fp)) {
1181
			/* read the next line */
1182
			$line = fgets($fp, 1024);
1183
1184
			$info = stream_get_meta_data($fp);
1185
			if ($info['timed_out'])
1186
				break;
1187
1188
			/* Get the client state */
1189
			if (strstr($line,"CONNECTED")) {
1190
				$client['status']="up";
1191
				$list = explode(",", $line);
1192
1193
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1194
				$client['virtual_addr']  = $list[3];
1195
				$client['remote_host'] = $list[4];
1196
			}
1197 453d9c96 jim-p
			if (strstr($line,"CONNECTING")) {
1198
				$client['status']="connecting";
1199
			}
1200
			if (strstr($line,"ASSIGN_IP")) {
1201
				$client['status']="waiting";
1202
				$list = explode(",", $line);
1203
1204
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1205
				$client['virtual_addr']  = $list[3];
1206
			}
1207
			if (strstr($line,"RECONNECTING")) {
1208
				$client['status']="reconnecting";
1209
				$list = explode(",", $line);
1210
1211
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1212
				$client['status'] .= "; " . $list[2];
1213
			}
1214 95305736 jim-p
			/* parse end of output line */
1215
			if (strstr($line, "END") || strstr($line, "ERROR"))
1216
				break;
1217
		}
1218
1219
		/* If up, get read/write stats */
1220
		if (strcmp($client['status'], "up") == 0) {
1221
			fputs($fp, "status 2\n");
1222
			/* recv all response lines */
1223
			while (!feof($fp)) {
1224
				/* read the next line */
1225
				$line = fgets($fp, 1024);
1226
1227
				$info = stream_get_meta_data($fp);
1228
				if ($info['timed_out'])
1229
					break;
1230
1231
				if (strstr($line,"TCP/UDP read bytes")) {
1232
					$list = explode(",", $line);
1233
					$client['bytes_recv'] = $list[1];
1234 53663f57 jim-p
				}
1235 95305736 jim-p
1236
				if (strstr($line,"TCP/UDP write bytes")) {
1237
					$list = explode(",", $line);
1238
					$client['bytes_sent'] = $list[1];
1239 53663f57 jim-p
				}
1240 95305736 jim-p
1241
				/* parse end of output line */
1242
				if (strstr($line, "END"))
1243
					break;
1244 53663f57 jim-p
			}
1245
		}
1246 95305736 jim-p
1247
		fclose($fp);
1248
1249
	} else {
1250
		$DisplayNote=true;
1251 2eaa97b9 jim-p
		$client['remote_host'] = "Unable to contact daemon";
1252
		$client['virtual_addr'] = "Service not running?";
1253 95305736 jim-p
		$client['bytes_recv'] = 0;
1254
		$client['bytes_sent'] = 0;
1255
		$client['connect_time'] = 0;
1256 53663f57 jim-p
	}
1257 95305736 jim-p
	return $client;
1258 53663f57 jim-p
}
1259 8e022a76 jim-p
1260
function openvpn_refresh_crls() {
1261
	global $g, $config;
1262
1263 a8f538a8 jim-p
	openvpn_create_dirs();
1264 8e022a76 jim-p
1265
	if (is_array($config['openvpn']['openvpn-server'])) {
1266
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1267
			if (empty($settings))
1268
				continue;
1269
			if (isset($settings['disable']))
1270
				continue;
1271
			// Write the settings for the keys
1272
			switch($settings['mode']) {
1273
				case 'p2p_tls':
1274
				case 'server_tls':
1275
				case 'server_tls_user':
1276
				case 'server_user':
1277
					if (!empty($settings['crlref'])) {
1278
						$crl = lookup_crl($settings['crlref']);
1279 728003c8 jim-p
						crl_update($crl);
1280 8e022a76 jim-p
						$fpath = $g['varetc_path']."/openvpn/server{$settings['vpnid']}.crl-verify";
1281
						file_put_contents($fpath, base64_decode($crl['text']));
1282
						@chmod($fpath, 0644);
1283
					}
1284
					break;
1285
			}
1286
		}
1287
	}
1288
}
1289
1290 a8f538a8 jim-p
function openvpn_create_dirs() {
1291
	global $g;
1292
	if (!is_dir("{$g['varetc_path']}/openvpn"))
1293
		safe_mkdir("{$g['varetc_path']}/openvpn", 0750);
1294
	if (!is_dir("{$g['varetc_path']}/openvpn-csc"))
1295
		safe_mkdir("{$g['varetc_path']}/openvpn-csc", 0750);
1296
}
1297
1298 91c44185 jim-p
function openvpn_get_interface_ip($ip, $mask) {
1299
	$baselong = ip2long32($ip) & ip2long($mask);
1300
	$ip1 = long2ip32($baselong + 1);
1301
	$ip2 = long2ip32($baselong + 2);
1302
	return array($ip1, $ip2);
1303
}
1304
1305
function openvpn_get_interface_ipv6($ipv6, $prefix) {
1306
	$basev6 = gen_subnetv6($ipv6, $prefix);
1307
	// Is there a better way to do this math?
1308
	$ipv6_arr = explode(':', $basev6);
1309
	$last = hexdec(array_pop($ipv6_arr));
1310 fe9c774d Phil Davis
	$ipv6_1 = Net_IPv6::compress(Net_IPv6::uncompress(implode(':', $ipv6_arr) . ':' . dechex($last + 1)));
1311
	$ipv6_2 = Net_IPv6::compress(Net_IPv6::uncompress(implode(':', $ipv6_arr) . ':' . dechex($last + 2)));
1312 91c44185 jim-p
	return array($ipv6_1, $ipv6_2);
1313
}
1314
1315
function openvpn_clear_route($mode, $settings) {
1316
	if (empty($settings['tunnel_network']))
1317
		return;
1318
	list($ip, $cidr) = explode('/', $settings['tunnel_network']);
1319
	$mask = gen_subnet_mask($cidr);
1320 6ca938cf jim-p
	$clear_route = false;
1321
1322 91c44185 jim-p
	switch($settings['mode']) {
1323 6ca938cf jim-p
		case 'shared_key':
1324
			$clear_route = true;
1325
			break;
1326 91c44185 jim-p
		case 'p2p_tls':
1327
		case 'p2p_shared_key':
1328 6d0b9fe9 jim-p
			if ($cidr == 30)
1329 6ca938cf jim-p
				$clear_route = true;
1330 91c44185 jim-p
			break;
1331
	}
1332 6ca938cf jim-p
1333 6d0b9fe9 jim-p
	if ($clear_route && !empty($ip) && !empty($mask)) {
1334 6ca938cf jim-p
		list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
1335
		$ip_to_clear = ($mode == "server") ? $ip1 : $ip2;
1336 615d7f0a Ermal
		/* XXX: Family for route? */
1337 6ca938cf jim-p
		mwexec("/sbin/route -q delete {$ip_to_clear}");
1338
	}
1339 91c44185 jim-p
}
1340
1341 5c427ce7 jim-p
function openvpn_gen_routes($value, $ipproto = "ipv4", $push = false, $iroute = false) {
1342 a28d40cb jim-p
	$routes = "";
1343
	if (empty($value))
1344
		return "";
1345
	$networks = explode(',', $value);
1346
1347
	foreach ($networks as $network) {
1348
		if ($ipproto == "ipv4")
1349 5c427ce7 jim-p
			$route = openvpn_gen_route_ipv4($network, $iroute);
1350 a28d40cb jim-p
		else
1351 5c427ce7 jim-p
			$route = openvpn_gen_route_ipv6($network, $iroute);
1352 a28d40cb jim-p
1353
		if ($push)
1354
			$routes .= "push \"{$route}\"\n";
1355
		else
1356
			$routes .= "{$route}\n";
1357
	}
1358
	return $routes;
1359
}
1360
1361 5c427ce7 jim-p
function openvpn_gen_route_ipv4($network, $iroute = false) {
1362
	$i = ($iroute) ? "i" : "";
1363 a28d40cb jim-p
	list($ip, $mask) = explode('/', trim($network));
1364
	$mask = gen_subnet_mask($mask);
1365 5c427ce7 jim-p
	return "{$i}route $ip $mask";
1366 a28d40cb jim-p
}
1367
1368 5c427ce7 jim-p
function openvpn_gen_route_ipv6($network, $iroute = false) {
1369
	$i = ($iroute) ? "i" : "";
1370 a28d40cb jim-p
	list($ipv6, $prefix) = explode('/', trim($network));
1371
	if (empty($prefix))
1372
		$prefix = "128";
1373 5c427ce7 jim-p
	return "{$i}route-ipv6 ${ipv6}/${prefix}";
1374 a28d40cb jim-p
}
1375
1376 699125b1 jim-p
function openvpn_get_settings($mode, $vpnid) {
1377
	global $config;
1378
1379
	if (is_array($config['openvpn']['openvpn-server'])) {
1380
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1381
			if (isset($settings['disable']))
1382
				continue;
1383
1384
			if ($vpnid != 0 && $vpnid == $settings['vpnid'])
1385
				return $settings;
1386
		}
1387
	}
1388
1389
	if (is_array($config['openvpn']['openvpn-client'])) {
1390
		foreach ($config['openvpn']['openvpn-client'] as $settings) {
1391
			if (isset($settings['disable']))
1392
				continue;
1393
1394
			if ($vpnid != 0 && $vpnid == $settings['vpnid'])
1395
				return $settings;
1396
		}
1397
	}
1398
1399
	return array();
1400
}
1401
1402
function openvpn_restart_by_vpnid($mode, $vpnid) {
1403
	$settings = openvpn_get_settings($mode, $vpnid);
1404
	openvpn_restart($mode, $settings);
1405
}
1406
1407 756720e2 Pierre POMES
?>