Project

General

Profile

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