Project

General

Profile

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