Project

General

Profile

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