Project

General

Profile

Download (36 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	openvpn.inc part of pfSense
4
	
5
	Copyright (C) 2008 Scott Ullrich <sullrich@gmail.com>
6
	All rights reserved.
7
	
8
	Copyright (C) 2006  Fernando Lemos
9
	All rights reserved.
10

    
11
	This file was rewritten from scratch by Fernando Lemos but
12
	*MIGHT* contain code previously written by:
13

    
14
	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
	
41
	DISABLE_PHP_LINT_CHECKING
42
	
43
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/openvpn	/usr/bin/openssl	/sbin/ifconfig
44
	pfSense_MODULE:	openvpn
45

    
46
*/
47
require_once('config.inc');
48
require_once("certs.inc");
49
require_once('pfsense-utils.inc');
50
require_once("auth.inc");
51

    
52
$openvpn_prots = array("UDP", "UDP6", "TCP", "TCP6");
53

    
54
$openvpn_dev_mode = array("tun", "tap");
55

    
56
/* 
57
 * The User Auth mode below is disabled because
58
 * OpenVPN erroneously requires that we provide
59
 * a CA configuration parameter. In this mode,
60
 * clients don't send a certificate so there is
61
 * no need for a CA. If we require that admins
62
 * provide one in the pfSense UI due to a bogus
63
 * requirement imposed by OpenVPN, it could be
64
 * considered very confusing ( I know I was ).
65
 *
66
 * -mgrooms
67
 */
68

    
69
$openvpn_dh_lengths = array(
70
	1024, 2048, 4096 );
71

    
72
$openvpn_cert_depths = array(
73
	1 => "One (Client+Server)",
74
	2 => "Two (Client+Intermediate+Server)",
75
	3 => "Three (Client+2xIntermediate+Server)",
76
	4 => "Four (Client+3xIntermediate+Server)",
77
	5 => "Five (Client+4xIntermediate+Server)"
78
);
79

    
80
$openvpn_server_modes = array(
81
	'p2p_tls' => gettext("Peer to Peer ( SSL/TLS )"),
82
	'p2p_shared_key' => gettext("Peer to Peer ( Shared Key )"),
83
	'server_tls' => gettext("Remote Access ( SSL/TLS )"),
84
	'server_user' => gettext("Remote Access ( User Auth )"),
85
	'server_tls_user' => gettext("Remote Access ( SSL/TLS + User Auth )"));
86

    
87
$openvpn_client_modes = array(
88
	'p2p_tls' => gettext("Peer to Peer ( SSL/TLS )"),
89
	'p2p_shared_key' => gettext("Peer to Peer ( Shared Key )") );
90

    
91
function openvpn_create_key() {
92

    
93
	$fp = popen("/usr/local/sbin/openvpn --genkey --secret /dev/stdout 2>/dev/null", "r");
94
	if (!$fp)
95
		return false;
96

    
97
	$rslt = stream_get_contents($fp);
98
	pclose($fp);
99

    
100
	return $rslt;
101
}
102

    
103
function openvpn_create_dhparams($bits) {
104

    
105
	$fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r");
106
	if (!$fp)
107
		return false;
108

    
109
	$rslt = stream_get_contents($fp);
110
	pclose($fp);
111

    
112
	return $rslt;
113
}
114

    
115
function openvpn_vpnid_used($vpnid) {
116
	global $config;
117

    
118
	if (is_array($config['openvpn']['openvpn-server']))
119
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
120
			if ($vpnid == $settings['vpnid'])
121
				return true;
122

    
123
	if (is_array($config['openvpn']['openvpn-client']))
124
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
125
			if ($vpnid == $settings['vpnid'])
126
				return true;
127

    
128
	return false;
129
}
130

    
131
function openvpn_vpnid_next() {
132

    
133
	$vpnid = 1;
134
	while(openvpn_vpnid_used($vpnid))
135
		$vpnid++;
136

    
137
	return $vpnid;
138
}
139

    
140
function openvpn_port_used($prot, $port) {
141
	global $config;
142

    
143
	if (is_array($config['openvpn']['openvpn-server']))
144
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
145
			if ($port == $settings['local_port'] &&
146
				$prot == $settings['protocol'] && !isset($settings['disable']))
147
				return $settings['vpnid'];
148

    
149
	if (is_array($config['openvpn']['openvpn-client']))
150
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
151
			if ($port == $settings['local_port'] &&
152
				$prot == $settings['protocol'] && !isset($settings['disable']))
153
				return $settings['vpnid'];
154

    
155
	return 0;
156
}
157

    
158
function openvpn_port_next($prot) {
159

    
160
	$port = 1194;
161
	while(openvpn_port_used($prot, $port))
162
		$port++;
163

    
164
	return $port;
165
}
166

    
167
function openvpn_get_cipherlist() {
168

    
169
	$ciphers = array();
170
	$cipher_out = shell_exec('/usr/local/sbin/openvpn --show-ciphers | /usr/bin/grep "default key" | /usr/bin/awk \'{print $1, "(" $2 "-" $3 ")";}\'');
171
	$cipher_lines = explode("\n", trim($cipher_out));
172
	sort($cipher_lines);
173
	foreach ($cipher_lines as $line) {
174
		$words = explode(' ', $line);
175
		$ciphers[$words[0]] = "{$words[0]} {$words[1]}";
176
	}
177
	$ciphers["none"] = gettext("None (No Encryption)");
178
	return $ciphers;
179
}
180

    
181
function openvpn_get_engines() {
182
	$openssl_engines = array('none' => 'No Hardware Crypto Acceleration');
183
	exec("/usr/bin/openssl engine", $openssl_engine_output);
184
	foreach ($openssl_engine_output as $oeo) {
185
		$linematch = array();
186
		preg_match("/\((.*)\)\s(.*)/", $oeo, $linematch);
187
		if ($linematch[1] != "dynamic")
188
			$openssl_engines[$linematch[1]] = $linematch[2];
189
	}
190
	return $openssl_engines;
191
}
192

    
193
function openvpn_validate_engine($engine) {
194
	$engines = openvpn_get_engines();
195
	return array_key_exists($engine, $engines);
196
}
197

    
198
function openvpn_validate_host($value, $name) {
199
	$value = trim($value);
200
	if (empty($value) || (!is_domain($value) && !is_ipaddr($value)))
201
		return sprintf(gettext("The field '%s' must contain a valid IP address or domain name."), $name);
202
	return false;
203
}
204

    
205
function openvpn_validate_port($value, $name) {
206
	$value = trim($value);
207
	if (empty($value) || !is_numeric($value) || $value < 0 || ($value > 65535))
208
		return sprintf(gettext("The field '%s' must contain a valid port, ranging from 0 to 65535."), $name);
209
	return false;
210
}
211

    
212
function openvpn_validate_cidr($value, $name, $multiple = false, $ipproto = "ipv4") {
213
	$value = trim($value);
214
	$error = false;
215
	if (empty($value))
216
		return false;
217
	$networks = explode(',', $value);
218

    
219
	if (!$multiple && (count($networks) > 1))
220
		return sprintf(gettext("The field '%s' must contain a single valid %s CIDR range."), $name, $ipproto);
221

    
222
	foreach ($networks as $network) {
223
		if ($ipproto == "ipv4")
224
			$error = !openvpn_validate_cidr_ipv4($network);
225
		else
226
			$error = !openvpn_validate_cidr_ipv6($network);
227
		if ($error)
228
			break;
229
	}
230

    
231
	if ($error)
232
		return sprintf(gettext("The field '%s' must contain only valid %s CIDR range(s) separated by commas."), $name, $ipproto);
233
	else
234
		return false;
235
}
236

    
237
function openvpn_validate_cidr_ipv4($value) {
238
	$value = trim($value);
239
	if (!empty($value)) {
240
		list($ip, $mask) = explode('/', $value);
241
		if (!is_ipaddrv4($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
242
			return false;
243
	}
244
	return true;
245
}
246

    
247
function openvpn_validate_cidr_ipv6($value) {
248
	$value = trim($value);
249
	if (!empty($value)) {
250
		list($ipv6, $prefix) = explode('/', $value);
251
		if (empty($prefix))
252
			$prefix = "128";
253
		if (!is_ipaddrv6($ipv6) or !is_numeric($prefix) or ($prefix > 128) or ($prefix < 0))
254
			return false;
255
	}
256
	return true;
257
}
258

    
259
function openvpn_add_dhcpopts(& $settings, & $conf) {
260

    
261
	if (!empty($settings['dns_domain'])) 
262
		$conf .= "push \"dhcp-option DOMAIN {$settings['dns_domain']}\"\n";
263

    
264
	if (!empty($settings['dns_server1']))
265
		$conf .= "push \"dhcp-option DNS {$settings['dns_server1']}\"\n";
266
	if (!empty($settings['dns_server2']))
267
		$conf .= "push \"dhcp-option DNS {$settings['dns_server2']}\"\n";
268
	if (!empty($settings['dns_server3']))
269
		$conf .= "push \"dhcp-option DNS {$settings['dns_server3']}\"\n";
270
	if (!empty($settings['dns_server4']))
271
		$conf .= "push \"dhcp-option DNS {$settings['dns_server4']}\"\n";
272

    
273
	if (!empty($settings['ntp_server1']))
274
		$conf .= "push \"dhcp-option NTP {$settings['ntp_server1']}\"\n";
275
	if (!empty($settings['ntp_server2']))
276
		$conf .= "push \"dhcp-option NTP {$settings['ntp_server2']}\"\n";
277

    
278
	if ($settings['netbios_enable']) {
279

    
280
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0))
281
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
282
		if (!empty($settings['dhcp_nbtscope'])) 
283
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
284

    
285
		if (!empty($settings['wins_server1']))
286
			$conf .= "push \"dhcp-option WINS {$settings['wins_server1']}\"\n";
287
		if (!empty($settings['wins_server2']))
288
			$conf .= "push \"dhcp-option WINS {$settings['wins_server2']}\"\n";
289

    
290
		if (!empty($settings['nbdd_server1']))
291
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server1']}\"\n";
292
	}
293

    
294
	if ($settings['gwredir']) 
295
		$conf .= "push \"redirect-gateway def1\"\n";
296
}
297

    
298
function openvpn_add_custom(& $settings, & $conf) {
299

    
300
	if ($settings['custom_options']) {
301

    
302
		$options = explode(';', $settings['custom_options']);
303

    
304
		if (is_array($options)) {
305
			foreach ($options as $option)
306
				$conf .= "$option\n";
307
		} else
308
			$conf .= "{$settings['custom_options']}\n";
309
	}
310
}
311

    
312
function openvpn_add_keyfile(& $data, & $conf, $mode_id, $directive, $opt = "") {
313
	global $g;
314

    
315
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.{$directive}";
316
	openvpn_create_dirs();
317
	file_put_contents($fpath, base64_decode($data));
318
	//chown($fpath, 'nobody');
319
	//chgrp($fpath, 'nobody');
320
	@chmod($fpath, 0600);
321

    
322
	$conf .= "{$directive} {$fpath} {$opt}\n";
323
}
324

    
325
function openvpn_reconfigure($mode, $settings) {
326
	global $g, $config;
327

    
328
	if (empty($settings))
329
		return;
330
	if (isset($settings['disable'])) 
331
		return;
332
	openvpn_create_dirs();
333
	/*
334
	 * NOTE: Deleting tap devices causes spontaneous reboots. Instead,
335
	 * we use a vpnid number which is allocated for a particular client
336
	 * or server configuration. ( see openvpn_vpnid_next() )
337
	 */
338

    
339
	$vpnid = $settings['vpnid'];
340
	$mode_id = $mode.$vpnid;
341

    
342
	if (isset($settings['dev_mode']))
343
		$tunname = "{$settings['dev_mode']}{$vpnid}";
344
	else {	/* defaults to tun */
345
		$tunname = "tun{$vpnid}";
346
		$settings['dev_mode'] = "tun";
347
	}
348

    
349
	if ($mode == "server")
350
		$devname = "ovpns{$vpnid}";
351
	else
352
		$devname = "ovpnc{$vpnid}";
353

    
354
	/* is our device already configured */
355
	if (mwexec("/sbin/ifconfig {$devname}", true)) {
356

    
357
		/* create the tap device if required */
358
		if (!file_exists("/dev/{$tunname}"))
359
			exec("/sbin/ifconfig {$tunname} create");
360

    
361
		/* rename the device */
362
		mwexec("/sbin/ifconfig {$tunname} name {$devname}");
363

    
364
		/* add the device to the openvpn group */
365
		mwexec("/sbin/ifconfig {$devname} group openvpn");
366
	}
367

    
368
	$pfile = $g['varrun_path'] . "/openvpn_{$mode_id}.pid";
369
	$proto = strtolower($settings['protocol']);
370
	if (substr($settings['protocol'], 0, 3) == "TCP")
371
			$proto = "{$proto}-{$mode}";
372
	$dev_mode = $settings['dev_mode'];
373
	$cipher = $settings['crypto'];
374

    
375
	$interface = get_failover_interface($settings['interface']);
376
	$ipaddr = $settings['ipaddr'];
377
	$ipaddrv6 = $settings['ipaddrv6'];
378

    
379
	// If a specific ip address (VIP) is requested, use it.
380
	// Otherwise, if a specific interface is requested, use it
381
	// If "any" interface was selected, local directive will be ommited.
382
	if (is_ipaddrv4($ipaddr)) {
383
		$iface_ip=$ipaddr;
384
	} else {
385
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
386
			$iface_ip=get_interface_ip($interface);
387
		}
388
	}
389
	if (is_ipaddrv6($ipaddrv6)) {
390
		$iface_ipv6=$ipaddrv6;
391
	} else {
392
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
393
			$iface_ipv6=get_interface_ipv6($interface);
394
		}
395
	}
396

    
397
	$conf  = "dev {$devname}\n";
398
	$conf .= "dev-type {$settings['dev_mode']}\n";
399
	switch($settings['dev_mode']) {
400
		case "tun":
401
			$conf .= "tun-ipv6\n";
402
			break;
403
	}
404
	$conf .= "dev-node /dev/{$tunname}\n";
405
	$conf .= "writepid {$pfile}\n";
406
	$conf .= "#user nobody\n";
407
	$conf .= "#group nobody\n";
408
	$conf .= "script-security 3\n";
409
	$conf .= "daemon\n";
410
	$conf .= "keepalive 10 60\n";
411
	$conf .= "ping-timer-rem\n";
412
	$conf .= "persist-tun\n";
413
	$conf .= "persist-key\n";
414
	$conf .= "proto {$proto}\n";
415
	$conf .= "cipher {$cipher}\n";
416
	$conf .= "up /usr/local/sbin/ovpn-linkup\n";
417
	$conf .= "down /usr/local/sbin/ovpn-linkdown\n";
418
	if (file_exists("/usr/local/sbin/openvpn.attributes.sh")) {
419
		switch($settings['mode']) {
420
			case 'server_user':
421
			case 'server_tls_user':
422
				$conf .= "client-connect /usr/local/sbin/openvpn.attributes.sh\n";
423
				$conf .= "client-disconnect /usr/local/sbin/openvpn.attributes.sh\n";
424
				break;
425
		}
426
	}
427

    
428
	/* Determine the local IP to use - and make sure it matches with the selected protocol. */
429
	if (is_ipaddrv4($iface_ip) && (stristr($settings['protocol'], "6") === false)) {
430
		$conf .= "local {$iface_ip}\n";
431
	} elseif (is_ipaddrv6($iface_ipv6) && (stristr($settings['protocol'], "6") !== false)) {
432
		$conf .= "local {$iface_ipv6}\n";
433
	}
434

    
435
	if (openvpn_validate_engine($settings['engine']) && ($settings['engine'] != "none"))
436
		$conf .= "engine {$settings['engine']}\n";
437

    
438
	// server specific settings
439
	if ($mode == 'server') {
440

    
441
		list($ip, $cidr) = explode('/', $settings['tunnel_network']);
442
		list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
443
		$mask = gen_subnet_mask($cidr);
444

    
445
		// configure tls modes
446
		switch($settings['mode']) {
447
			case 'p2p_tls':
448
			case 'server_tls':
449
			case 'server_user':
450
			case 'server_tls_user':
451
				$conf .= "tls-server\n";
452
				break;
453
		}
454

    
455
		// configure p2p/server modes
456
		switch($settings['mode']) {
457
			case 'p2p_tls':
458
				// If the CIDR is less than a /30, OpenVPN will complain if you try to
459
				//  use the server directive. It works for a single client without it.
460
				//  See ticket #1417
461
				if (!empty($ip) && !empty($mask) && ($cidr < 30)) {
462
					$conf .= "server {$ip} {$mask}\n";
463
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
464
					if(is_ipaddr($ipv6))
465
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
466
				}
467
			case 'p2p_shared_key':
468
				if (!empty($ip) && !empty($mask)) {
469
					list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
470
					if ($settings['dev_mode'] == 'tun')
471
						$conf .= "ifconfig {$ip1} {$ip2}\n";
472
					else
473
						$conf .= "ifconfig {$ip1} {$mask}\n";
474
				}
475
				if (!empty($ipv6) && !empty($prefix)) {
476
					list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
477
					if ($settings['dev_mode'] == 'tun')
478
						$conf .= "ifconfig-ipv6 {$ipv6_1} {$ipv6_2}\n";
479
					else
480
						$conf .= "ifconfig {$ipv6_1} {$prefix}\n";
481
				}
482
				break;
483
			case 'server_tls':
484
			case 'server_user':
485
			case 'server_tls_user':
486
				if (!empty($ip) && !empty($mask)) {
487
					$conf .= "server {$ip} {$mask}\n";
488
					if(is_ipaddr($ipv6))
489
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
490
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
491
				} else {
492
					if ($settings['serverbridge_dhcp']) {
493
						if ((!empty($settings['serverbridge_interface'])) && (strcmp($settings['serverbridge_interface'], "none"))) {
494
							$biface_ip=get_interface_ip($settings['serverbridge_interface']);
495
							$biface_sm=gen_subnet_mask(get_interface_subnet($settings['serverbridge_interface']));
496
							if (is_ipaddrv4($biface_ip) && is_ipaddrv4($settings['serverbridge_dhcp_start']) && is_ipaddrv4($settings['serverbridge_dhcp_end'])) {
497
								$conf .= "server-bridge {$biface_ip} {$biface_sm} {$settings['serverbridge_dhcp_start']} {$settings['serverbridge_dhcp_end']}\n";
498
							} else {
499
								$conf .= "mode server\n";
500
							}
501
						} else {
502
							$conf .= "mode server\n";
503
						}
504
					}
505
				}
506
				break;
507
		}
508

    
509
		// configure user auth modes
510
		switch($settings['mode']) {
511
			case 'server_user':
512
				$conf .= "client-cert-not-required\n";
513
			case 'server_tls_user':
514
				/* username-as-common-name is not compatible with server-bridge */
515
				if (stristr($conf, "server-bridge") === false)
516
					$conf .= "username-as-common-name\n";
517
				if (!empty($settings['authmode'])) {
518
					$authcfgs = explode(",", $settings['authmode']);
519
					$sed = "\$authmodes=array(";
520
					$firstsed = 0;
521
					foreach ($authcfgs as $authcfg) {
522
						if ($firstsed > 0)
523
							$sed .= ",";
524
						$firstsed = 1;
525
						$sed .= "\"{$authcfg}\"";
526
					}
527
					$sed .= ");\\\n";
528
					if ($settings['strictusercn'])
529
						$sed .= "\$strictusercn = true;";
530
					$sed .= " \$modeid = \"{$mode_id}\";";
531
					mwexec("/bin/cat /etc/inc/openvpn.auth-user.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/openvpn/{$mode_id}.php");
532
					mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.php");
533
					$conf .= "auth-user-pass-verify {$g['varetc_path']}/openvpn/{$mode_id}.php via-env\n";
534
				}
535
				break;
536
		}
537
		if (!isset($settings['cert_depth']) && (strstr($settings['mode'], 'tls')))
538
			$settings['cert_depth'] = 1;
539
		if (is_numeric($settings['cert_depth'])) {
540
			$sed = "";
541
			$cert = lookup_cert($settings['certref']);
542
			$servercn = cert_get_cn($cert['crt']);
543
			$sed .= "\$server_cn = \"{$servercn}\";\\\n";
544
			$sed .= "\$allowed_depth = {$settings['cert_depth']};\\\n";
545
			mwexec("/bin/cat /etc/inc/openvpn.tls-verify.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php");
546
			mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php");
547
			$conf .= "tls-verify {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php\n";
548
		}
549

    
550
		// The local port to listen on
551
		$conf .= "lport {$settings['local_port']}\n";
552

    
553
		// The management port to listen on
554
		// Use unix socket to overcome the problem on any type of server
555
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
556
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
557

    
558
		if ($settings['maxclients'])
559
			$conf .= "max-clients {$settings['maxclients']}\n";
560

    
561
		// Can we push routes
562
		if ($settings['local_network']) {
563
			$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
564
		}
565
		if ($settings['local_networkv6']) {
566
			$conf .= openvpn_gen_routes($settings['local_networkv6'], "ipv6", true);
567
		}
568

    
569
		switch($settings['mode']) {
570
			case 'server_tls':
571
			case 'server_user':
572
			case 'server_tls_user':
573
				// Configure client dhcp options
574
				openvpn_add_dhcpopts($settings, $conf);
575
				if ($settings['client2client'])
576
					$conf .= "client-to-client\n";
577
				break;
578
		}
579
		if (isset($settings['duplicate_cn']))
580
			$conf .= "duplicate-cn\n";
581
	}
582

    
583
	// client specific settings
584

    
585
	if ($mode == 'client') {
586

    
587
		// configure p2p mode
588
		switch($settings['mode']) {
589
			case 'p2p_tls':
590
				$conf .= "tls-client\n";
591
			case 'shared_key':
592
				$conf .= "client\n";
593
				break;
594
		}
595

    
596
		// If there is no bind option at all (ip and/or port), add "nobind" directive
597
		//  Otherwise, use the local port if defined, failing that, use lport 0 to 
598
		//  ensure a random source port.
599
		if ((empty($iface_ip)) && (!$settings['local_port']))
600
			$conf .= "nobind\n";
601
		elseif ($settings['local_port'])
602
			$conf .= "lport {$settings['local_port']}\n";
603
		else
604
			$conf .= "lport 0\n";
605

    
606
		// Use unix socket to overcome the problem on any type of server
607
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
608

    
609
		// The remote server
610
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
611

    
612
		if (!empty($settings['use_shaper']))
613
			$conf .= "shaper {$settings['use_shaper']}\n";
614

    
615
		if (!empty($settings['tunnel_network'])) {
616
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
617
			$mask = gen_subnet_mask($mask);
618
			list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
619
			if ($settings['dev_mode'] == 'tun')
620
				$conf .= "ifconfig {$ip2} {$ip1}\n";
621
			else
622
				$conf .= "ifconfig {$ip2} {$mask}\n";
623
		}
624

    
625
		if (!empty($settings['tunnel_networkv6'])) {
626
			list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
627
			list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
628
			if ($settings['dev_mode'] == 'tun')
629
				$conf .= "ifconfig-ipv6 {$ipv6_2} {$ipv6_1}\n";
630
			else
631
				$conf .= "ifconfig {$ipv6_2} {$prefix}\n";
632
		}
633

    
634
		if ($settings['proxy_addr']) {
635
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
636
			if ($settings['proxy_authtype'] != "none") {
637
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
638
				$proxypas = "{$settings['proxy_user']}\n";
639
				$proxypas .= "{$settings['proxy_passwd']}\n";
640
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
641
			}
642
			$conf .= " \n";
643
		}
644
	}
645

    
646
	// Add a remote network route if set, and only for p2p modes.
647
	if ((substr($settings['mode'], 0, 3) == "p2p") && is_subnet($settings['remote_network'])) {
648
		$conf .= openvpn_gen_routes($settings['remote_network'], "ipv4", false);
649
	}
650
	// Add a remote network route if set, and only for p2p modes.
651
	if ((substr($settings['mode'], 0, 3) == "p2p") && is_subnet($settings['remote_networkv6'])) {
652
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false);
653
	}
654

    
655
	// Write the settings for the keys
656
	switch($settings['mode']) {
657
		case 'p2p_shared_key':
658
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
659
			break;
660
		case 'p2p_tls':
661
		case 'server_tls':
662
		case 'server_tls_user':
663
		case 'server_user':
664
			$ca = lookup_ca($settings['caref']);
665
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
666
			$cert = lookup_cert($settings['certref']);
667
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
668
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
669
			if ($mode == 'server')
670
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
671
			if (!empty($settings['crlref'])) {
672
				$crl = lookup_crl($settings['crlref']);
673
				crl_update($crl);
674
				openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify");
675
			}
676
			if ($settings['tls']) {
677
				if ($mode == "server") 
678
					$tlsopt = 0;
679
				else
680
					$tlsopt = 1;
681
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
682
			}
683
			break;
684
	}
685

    
686
	if ($settings['compression'])
687
		$conf .= "comp-lzo\n";
688

    
689
	if ($settings['passtos'])
690
		$conf .= "passtos\n";
691

    
692
	if ($settings['resolve_retry'])
693
		$conf .= "resolv-retry infinite\n";
694

    
695
	if ($settings['dynamic_ip']) {
696
		$conf .= "persist-remote-ip\n";
697
		$conf .= "float\n";
698
	}
699

    
700
	if ($settings['topology_subnet']) {
701
		$conf .= "topology subnet\n";
702
	}
703

    
704
	openvpn_add_custom($settings, $conf);
705

    
706
	openvpn_create_dirs();
707
	$fpath = "{$g['varetc_path']}/openvpn/{$mode_id}.conf";
708
	file_put_contents($fpath, $conf);
709
	unset($conf);
710
	//chown($fpath, 'nobody');
711
	//chgrp($fpath, 'nobody');
712
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
713
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
714
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
715
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
716
}
717

    
718
function openvpn_restart($mode, $settings) {
719
	global $g, $config;
720

    
721
	$vpnid = $settings['vpnid'];
722
	$mode_id = $mode.$vpnid;
723

    
724
	/* kill the process if running */
725
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
726
	if (file_exists($pfile)) {
727

    
728
		/* read the pid file */
729
		$pid = rtrim(file_get_contents($pfile));
730
		unlink($pfile);
731

    
732
		/* send a term signal to the process */
733
		posix_kill($pid, SIGTERM);
734

    
735
		/* wait until the process exits */
736
		while(posix_kill($pid, 0))
737
			usleep(250000);
738
	}
739

    
740
	if (isset($settings['disable']))
741
		return;
742

    
743
	/* Do not start a client if we are a CARP backup on this vip! */
744
	if (($mode == "client") && strstr($settings['interface'], "_vip") && (get_carp_interface_status($settings['interface']) == "BACKUP"))
745
		return;
746

    
747
	/* start the new process */
748
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
749
	openvpn_clear_route($mode, $settings);
750
	mwexec_bg("/usr/local/sbin/openvpn --config {$fpath}");
751

    
752
	if (!$g['booting'])
753
		send_event("filter reload");
754
}
755

    
756
function openvpn_delete($mode, & $settings) {
757
	global $g, $config;
758

    
759
	$vpnid = $settings['vpnid'];
760
	$mode_id = $mode.$vpnid;
761

    
762
	if (isset($settings['dev_mode']))
763
		$tunname = "{$settings['dev_mode']}{$vpnid}";
764
	else {  /* defaults to tun */
765
		$tunname = "tun{$vpnid}";
766
	}
767

    
768
	if ($mode == "server")
769
		$devname = "ovpns{$vpnid}";
770
	else
771
		$devname = "ovpnc{$vpnid}";
772

    
773
	/* kill the process if running */
774
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
775
	if (file_exists($pfile)) {
776

    
777
		/* read the pid file */
778
		$pid = trim(file_get_contents($pfile));
779
		unlink($pfile);
780

    
781
		/* send a term signal to the process */
782
		posix_kill($pid, SIGTERM);
783
	}
784

    
785
	/* remove the device from the openvpn group */
786
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
787

    
788
	/* restore the original adapter name */
789
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
790

    
791
	/* remove the configuration files */
792
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
793
}
794

    
795
function openvpn_resync_csc(& $settings) {
796
	global $g, $config;
797

    
798
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
799

    
800
	if (isset($settings['disable'])) {
801
		unlink_if_exists($fpath);
802
		return;
803
	}
804
	openvpn_create_dirs();
805

    
806
	$conf = '';
807
	if ($settings['block'])
808
		$conf .= "disable\n";
809

    
810
	if ($settings['push_reset'])
811
		$conf .= "push-reset\n";
812

    
813
	if (!empty($settings['tunnel_network'])) {
814
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
815
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
816
		$serverip = long2ip32($baselong + 1);
817
		$clientip = long2ip32($baselong + 2);
818
		/* Because this is being pushed, the order from the client's point of view. */
819
		if ($settings['dev_mode'] != 'tap')
820
			$conf .= "ifconfig-push {$clientip} {$serverip}\n";
821
		else
822
			$conf .= "ifconfig-push {$clientip} {$mask}\n";
823
	}
824

    
825
	openvpn_add_dhcpopts($settings, $conf);
826

    
827
	if ($settings['gwredir'])
828
		$conf .= "push \"redirect-gateway def1\"\n";
829

    
830
	openvpn_add_custom($settings, $conf);
831

    
832
	file_put_contents($fpath, $conf);
833
	chown($fpath, 'nobody');
834
	chgrp($fpath, 'nobody');
835
}
836

    
837
function openvpn_delete_csc(& $settings) {
838
	global $g, $config;
839

    
840
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
841
	unlink_if_exists($fpath);
842
}
843

    
844
// Resync the configuration and restart the VPN
845
function openvpn_resync($mode, $settings) {
846
	openvpn_reconfigure($mode, $settings);
847
	openvpn_restart($mode, $settings);
848
}
849

    
850
// Resync and restart all VPNs
851
function openvpn_resync_all($interface = "") {
852
	global $g, $config;
853

    
854
	if ($g['platform'] == 'jail')
855
		return;
856
	openvpn_create_dirs();
857

    
858
	if (!is_array($config['openvpn']))
859
		$config['openvpn'] = array();
860

    
861
/*
862
	if (!$config['openvpn']['dh-parameters']) {
863
		echo "Configuring OpenVPN Parameters ...\n";
864
		$dh_parameters = openvpn_create_dhparams(1024);
865
		$dh_parameters = base64_encode($dh_parameters);
866
		$config['openvpn']['dh-parameters'] = $dh_parameters;
867
		write_config("OpenVPN DH parameters");
868
	}
869

    
870
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
871
	if (!file_exists($path_ovdh)) {
872
		$dh_parameters = $config['openvpn']['dh-parameters'];
873
		$dh_parameters = base64_decode($dh_parameters);
874
		file_put_contents($path_ovdh, $dh_parameters);
875
	}
876
*/
877
	if ($interface <> "")
878
		log_error("Resyncing OpenVPN instances for interface " . convert_friendly_interface_to_friendly_descr($interface) . ".");
879
	else
880
		log_error("Resyncing OpenVPN instances."); 
881

    
882
	if (is_array($config['openvpn']['openvpn-server'])) {
883
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
884
			if ($interface <> "" && $interface != $settings['interface'])
885
				continue;
886
			openvpn_resync('server', $settings);
887
		}
888
	}
889

    
890
	if (is_array($config['openvpn']['openvpn-client'])) {
891
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
892
			if ($interface <> "" && $interface != $settings['interface'])
893
				continue;
894
			openvpn_resync('client', $settings);
895
		}
896
	}
897

    
898
	if (is_array($config['openvpn']['openvpn-csc']))
899
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
900
			openvpn_resync_csc($settings);
901

    
902
}
903

    
904
function openvpn_get_active_servers($type="multipoint") {
905
	global $config, $g;
906

    
907
	$servers = array();
908
	if (is_array($config['openvpn']['openvpn-server'])) {
909
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
910
			if (empty($settings) || isset($settings['disable']))
911
				continue;
912

    
913
			$prot = $settings['protocol'];
914
			$port = $settings['local_port'];
915
	
916
			$server = array();
917
			$server['port'] = ($settings['local_port']) ? $settings['local_port'] : 1194;
918
			$server['mode'] = $settings['mode'];
919
			if ($settings['description'])
920
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
921
			else
922
				$server['name'] = "Server {$prot}:{$port}";
923
			$server['conns'] = array();
924
	
925
			$vpnid = $settings['vpnid'];
926
			$mode_id = "server{$vpnid}";
927
			$server['mgmt'] = $mode_id;
928
			$socket = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
929
			list($tn, $sm) = explode('/', $settings['tunnel_network']);
930

    
931
			if ((($server['mode'] == "p2p_shared_key") || ($sm >= 30) ) && ($type == "p2p"))
932
				$servers[] = openvpn_get_client_status($server, $socket);
933
			elseif (($server['mode'] != "p2p_shared_key") && ($type == "multipoint") && ($sm < 30))
934
				$servers[] = openvpn_get_server_status($server, $socket);
935

    
936
		}
937
	}
938
	return $servers;
939
}
940

    
941
function openvpn_get_server_status($server, $socket) {
942
	$errval;
943
	$errstr;
944
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
945
	if ($fp) {
946
		stream_set_timeout($fp, 1);
947

    
948
		/* send our status request */
949
		fputs($fp, "status 2\n");
950

    
951
		/* recv all response lines */
952
		while (!feof($fp)) {
953

    
954
			/* read the next line */
955
			$line = fgets($fp, 1024);
956

    
957
			$info = stream_get_meta_data($fp);
958
			if ($info['timed_out'])
959
				break;
960

    
961
			/* parse header list line */
962
			if (strstr($line, "HEADER"))
963
				continue;
964

    
965
			/* parse end of output line */
966
			if (strstr($line, "END") || strstr($line, "ERROR"))
967
				break;
968

    
969
			/* parse client list line */
970
			if (strstr($line, "CLIENT_LIST")) {
971
				$list = explode(",", $line);
972
				$conn = array();
973
				$conn['common_name'] = $list[1];
974
				$conn['remote_host'] = $list[2];
975
				$conn['virtual_addr'] = $list[3];
976
				$conn['bytes_recv'] = $list[4];
977
				$conn['bytes_sent'] = $list[5];
978
				$conn['connect_time'] = $list[6];
979
				$server['conns'][] = $conn;
980
			}
981
			/* parse routing table lines */
982
			if (strstr($line, "ROUTING_TABLE")) {
983
				$list = explode(",", $line);
984
				$conn = array();
985
				$conn['virtual_addr'] = $list[1];
986
				$conn['common_name'] = $list[2];
987
				$conn['remote_host'] = $list[3];
988
				$conn['last_time'] = $list[4];
989
				$server['routes'][] = $conn;
990
			}
991
		}
992

    
993
		/* cleanup */
994
		fclose($fp);
995
	} else {
996
		$conn = array();
997
		$conn['common_name'] = "[error]";
998
		$conn['remote_host'] = "Management Daemon Unreachable";
999
		$conn['virtual_addr'] = "";
1000
		$conn['bytes_recv'] = 0;
1001
		$conn['bytes_sent'] = 0;
1002
		$conn['connect_time'] = 0;
1003
		$server['conns'][] = $conn;
1004
	}
1005
	return $server;
1006
}
1007

    
1008
function openvpn_get_active_clients() {
1009
	global $config, $g;
1010

    
1011
	$clients = array();
1012
	if (is_array($config['openvpn']['openvpn-client'])) {
1013
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
1014
	
1015
			if (empty($settings) || isset($settings['disable']))
1016
				continue;
1017

    
1018
			$prot = $settings['protocol'];
1019
			$port = ($settings['local_port']) ? ":{$settings['local_port']}" : "";
1020
	
1021
			$client = array();
1022
			$client['port'] = $settings['local_port'];
1023
			if ($settings['description'])
1024
				$client['name'] = "{$settings['description']} {$prot}{$port}";
1025
			else
1026
				$client['name'] = "Client {$prot}{$port}";
1027
	
1028
			$vpnid = $settings['vpnid'];
1029
			$mode_id = "client{$vpnid}";
1030
			$client['mgmt'] = $mode_id;
1031
			$socket = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
1032
			$client['status']="down";
1033

    
1034
			$clients[] = openvpn_get_client_status($client, $socket);
1035
		}
1036
	}
1037
	return $clients;
1038
}
1039

    
1040
function openvpn_get_client_status($client, $socket) {
1041
	$errval;
1042
	$errstr;
1043
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
1044
	if ($fp) {
1045
		stream_set_timeout($fp, 1);
1046
		/* send our status request */
1047
		fputs($fp, "state 1\n");
1048

    
1049
		/* recv all response lines */
1050
		while (!feof($fp)) {
1051
			/* read the next line */
1052
			$line = fgets($fp, 1024);
1053

    
1054
			$info = stream_get_meta_data($fp);
1055
			if ($info['timed_out'])
1056
				break;
1057

    
1058
			/* Get the client state */
1059
			if (strstr($line,"CONNECTED")) {
1060
				$client['status']="up";
1061
				$list = explode(",", $line);
1062

    
1063
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1064
				$client['virtual_addr']  = $list[3];
1065
				$client['remote_host'] = $list[4];
1066
			}
1067
			if (strstr($line,"CONNECTING")) {
1068
				$client['status']="connecting";
1069
			}
1070
			if (strstr($line,"ASSIGN_IP")) {
1071
				$client['status']="waiting";
1072
				$list = explode(",", $line);
1073

    
1074
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1075
				$client['virtual_addr']  = $list[3];
1076
			}
1077
			if (strstr($line,"RECONNECTING")) {
1078
				$client['status']="reconnecting";
1079
				$list = explode(",", $line);
1080

    
1081
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1082
				$client['status'] .= "; " . $list[2];
1083
			}
1084
			/* parse end of output line */
1085
			if (strstr($line, "END") || strstr($line, "ERROR"))
1086
				break;
1087
		}
1088

    
1089
		/* If up, get read/write stats */
1090
		if (strcmp($client['status'], "up") == 0) {
1091
			fputs($fp, "status 2\n");
1092
			/* recv all response lines */
1093
			while (!feof($fp)) {
1094
				/* read the next line */
1095
				$line = fgets($fp, 1024);
1096

    
1097
				$info = stream_get_meta_data($fp);
1098
				if ($info['timed_out'])
1099
					break;
1100

    
1101
				if (strstr($line,"TCP/UDP read bytes")) {
1102
					$list = explode(",", $line);
1103
					$client['bytes_recv'] = $list[1];
1104
				}
1105

    
1106
				if (strstr($line,"TCP/UDP write bytes")) {
1107
					$list = explode(",", $line);
1108
					$client['bytes_sent'] = $list[1];
1109
				}
1110

    
1111
				/* parse end of output line */
1112
				if (strstr($line, "END"))
1113
					break;
1114
			}
1115
		}
1116

    
1117
		fclose($fp);
1118

    
1119
	} else {
1120
		$DisplayNote=true;
1121
		$client['remote_host'] = "No Management Daemon";
1122
		$client['virtual_addr'] = "See Note Below";
1123
		$client['bytes_recv'] = 0;
1124
		$client['bytes_sent'] = 0;
1125
		$client['connect_time'] = 0;
1126
	}
1127
	return $client;
1128
}
1129

    
1130
function openvpn_refresh_crls() {
1131
	global $g, $config;
1132

    
1133
	openvpn_create_dirs();
1134

    
1135
	if (is_array($config['openvpn']['openvpn-server'])) {
1136
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1137
			if (empty($settings))
1138
				continue;
1139
			if (isset($settings['disable']))
1140
				continue;
1141
			// Write the settings for the keys
1142
			switch($settings['mode']) {
1143
				case 'p2p_tls':
1144
				case 'server_tls':
1145
				case 'server_tls_user':
1146
				case 'server_user':
1147
					if (!empty($settings['crlref'])) {
1148
						$crl = lookup_crl($settings['crlref']);
1149
						crl_update($crl);
1150
						$fpath = $g['varetc_path']."/openvpn/server{$settings['vpnid']}.crl-verify";
1151
						file_put_contents($fpath, base64_decode($crl['text']));
1152
						@chmod($fpath, 0644);
1153
					}
1154
					break;
1155
			}
1156
		}
1157
	}
1158
}
1159

    
1160
function openvpn_create_dirs() {
1161
	global $g;
1162
	if (!is_dir("{$g['varetc_path']}/openvpn"))
1163
		safe_mkdir("{$g['varetc_path']}/openvpn", 0750);
1164
	if (!is_dir("{$g['varetc_path']}/openvpn-csc"))
1165
		safe_mkdir("{$g['varetc_path']}/openvpn-csc", 0750);
1166
}
1167

    
1168
function openvpn_get_interface_ip($ip, $mask) {
1169
	$baselong = ip2long32($ip) & ip2long($mask);
1170
	$ip1 = long2ip32($baselong + 1);
1171
	$ip2 = long2ip32($baselong + 2);
1172
	return array($ip1, $ip2);
1173
}
1174

    
1175
function openvpn_get_interface_ipv6($ipv6, $prefix) {
1176
	$basev6 = gen_subnetv6($ipv6, $prefix);
1177
	// Is there a better way to do this math?
1178
	$ipv6_arr = explode(':', $basev6);
1179
	$last = hexdec(array_pop($ipv6_arr));
1180
	$ipv6_1 = Net_IPv6::compress(implode(':', $ipv6_arr) . ':' . dechex($last + 1));
1181
	$ipv6_2 = Net_IPv6::compress(implode(':', $ipv6_arr) . ':' . dechex($last + 2));
1182
	return array($ipv6_1, $ipv6_2);
1183
}
1184

    
1185
function openvpn_clear_route($mode, $settings) {
1186
	if (empty($settings['tunnel_network']))
1187
		return;
1188
	list($ip, $cidr) = explode('/', $settings['tunnel_network']);
1189
	$mask = gen_subnet_mask($cidr);
1190
	switch($settings['mode']) {
1191
		case 'p2p_tls':
1192
		case 'p2p_shared_key':
1193
		case 'shared_key':
1194
			if (!empty($ip) && !empty($mask) && ($cidr == 30)) {
1195
				list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
1196
				$ip_to_clear = ($mode == "server") ? $ip1 : $ip2;
1197
				mwexec("/sbin/route -q delete {$ip_to_clear}");
1198
			}
1199
			break;
1200
	}
1201
}
1202

    
1203
function openvpn_gen_routes($value, $ipproto = "ipv4", $push = false) {
1204
	$routes = "";
1205
	if (empty($value))
1206
		return "";
1207
	$networks = explode(',', $value);
1208

    
1209
	foreach ($networks as $network) {
1210
		if ($ipproto == "ipv4")
1211
			$route = openvpn_gen_route_ipv4($network);
1212
		else
1213
			$route = openvpn_gen_route_ipv6($network);
1214

    
1215
		if ($push)
1216
			$routes .= "push \"{$route}\"\n";
1217
		else
1218
			$routes .= "{$route}\n";
1219
	}
1220
	return $routes;
1221
}
1222

    
1223
function openvpn_gen_route_ipv4($network) {
1224
	list($ip, $mask) = explode('/', trim($network));
1225
	$mask = gen_subnet_mask($mask);
1226
	return "route $ip $mask";
1227
}
1228

    
1229
function openvpn_gen_route_ipv6($network) {
1230
	list($ipv6, $prefix) = explode('/', trim($network));
1231
	if (empty($prefix))
1232
		$prefix = "128";
1233
	return "route-ipv6 ${ipv6}/${prefix}";
1234
}
1235

    
1236
?>
(37-37/67)