Projet

Général

Profil

Télécharger (42,4 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / openvpn.inc @ b1e8e675

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