Project

General

Profile

Download (34.7 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 b1ad443d Scott Ullrich
/*
3 9a6d6728 Ermal
	openvpn.inc part of pfSense
4 33ab8aa5 Scott Ullrich
	
5
	Copyright (C) 2008 Scott Ullrich <sullrich@gmail.com>
6
	All rights reserved.
7
	
8 b1ad443d Scott Ullrich
	Copyright (C) 2006  Fernando Lemos
9
	All rights reserved.
10
11 33ab8aa5 Scott Ullrich
	This file was rewritten from scratch by Fernando Lemos but
12
	*MIGHT* contain code previously written by:
13
14 b1ad443d Scott Ullrich
	Copyright (C) 2005 Peter Allgeyer <allgeyer_AT_web.de>
15
	All rights reserved.
16
17
	Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
18
	All rights reserved.
19
20
	Redistribution and use in source and binary forms, with or without
21
	modification, are permitted provided that the following conditions are met:
22
23
	1. Redistributions of source code must retain the above copyright notices,
24
	   this list of conditions and the following disclaimer.
25
26
	2. Redistributions in binary form must reproduce the above copyright
27
	   notices, this list of conditions and the following disclaimer in the
28
	   documentation and/or other materials provided with the distribution.
29
30
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
32
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
	POSSIBILITY OF SUCH DAMAGE.
40 523855b0 Scott Ullrich
	
41
	DISABLE_PHP_LINT_CHECKING
42
	
43
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/openvpn	/usr/bin/openssl	/sbin/ifconfig
44
	pfSense_MODULE:	openvpn
45 b1ad443d Scott Ullrich
46 523855b0 Scott Ullrich
*/
47 8dc3ef67 Scott Ullrich
require_once('config.inc');
48 32a7a1f6 Ermal Lu?i
require_once("certs.inc");
49 36df0acc Scott Ullrich
require_once('pfsense-utils.inc');
50 c61e4626 Ermal Lu?i
require_once("auth.inc");
51 8dc3ef67 Scott Ullrich
52 6714bbdc jim-p
$openvpn_prots = array("UDP", "UDP6", "TCP", "TCP6");
53 702a4702 Scott Ullrich
54 691fbf14 Ermal Lu?i
$openvpn_dev_mode = array("tun", "tap");
55
56 3c11bd3c Matthew Grooms
/* 
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 fe787fc7 Matthew Grooms
$openvpn_dh_lengths = array(
70
	1024, 2048, 4096 );
71
72 98963f27 jim-p
$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 3c11bd3c Matthew Grooms
$openvpn_server_modes = array(
81 4aa02281 Carlos Eduardo Ramos
	'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 3c11bd3c Matthew Grooms
87
$openvpn_client_modes = array(
88 4aa02281 Carlos Eduardo Ramos
	'p2p_tls' => gettext("Peer to Peer ( SSL/TLS )"),
89
	'p2p_shared_key' => gettext("Peer to Peer ( Shared Key )") );
90 3c11bd3c Matthew Grooms
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 d799787e Matthew Grooms
103 8411b218 Matthew Grooms
function openvpn_create_dhparams($bits) {
104 34bc1324 Matthew Grooms
105 3c11bd3c Matthew Grooms
	$fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r");
106 34bc1324 Matthew Grooms
	if (!$fp)
107
		return false;
108
109
	$rslt = stream_get_contents($fp);
110
	pclose($fp);
111
112
	return $rslt;
113
}
114
115 d799787e Matthew Grooms
function openvpn_vpnid_used($vpnid) {
116 8be2d6d3 Ermal Luçi
	global $config;
117
118 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-server']))
119 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
120 f432e364 Matthew Grooms
			if ($vpnid == $settings['vpnid'])
121 d799787e Matthew Grooms
				return true;
122
123
	if (is_array($config['openvpn']['openvpn-client']))
124 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
125 f432e364 Matthew Grooms
			if ($vpnid == $settings['vpnid'])
126 d799787e Matthew Grooms
				return true;
127 04a6e900 Ermal Luçi
128 d799787e Matthew Grooms
	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 f432e364 Matthew Grooms
function openvpn_port_used($prot, $port) {
141
	global $config;
142
143
	if (is_array($config['openvpn']['openvpn-server']))
144 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
145 f432e364 Matthew Grooms
			if ($port == $settings['local_port'] &&
146 d9489532 Chris Buechler
				$prot == $settings['protocol'] && !isset($settings['disable']))
147 f432e364 Matthew Grooms
				return $settings['vpnid'];
148
149
	if (is_array($config['openvpn']['openvpn-client']))
150 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
151 f432e364 Matthew Grooms
			if ($port == $settings['local_port'] &&
152 d9489532 Chris Buechler
				$prot == $settings['protocol'] && !isset($settings['disable']))
153 f432e364 Matthew Grooms
				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 d799787e Matthew Grooms
function openvpn_get_cipherlist() {
168
169
	$ciphers = array();
170 5a7cc1f9 Ermal
	$cipher_out = shell_exec('/usr/local/sbin/openvpn --show-ciphers | /usr/bin/grep "default key" | /usr/bin/awk \'{print $1, "(" $2 "-" $3 ")";}\'');
171 d799787e Matthew Grooms
	$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 8be2d6d3 Ermal Luçi
	}
177 4aa02281 Carlos Eduardo Ramos
	$ciphers["none"] = gettext("None (No Encryption)");
178 d799787e Matthew Grooms
	return $ciphers;
179
}
180
181 582c58ae jim-p
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 d799787e Matthew Grooms
function openvpn_validate_host($value, $name) {
199
	$value = trim($value);
200 3e2bd5de Ermal Lu?i
	if (empty($value) || (!is_domain($value) && !is_ipaddr($value)))
201 4aa02281 Carlos Eduardo Ramos
		return sprintf(gettext("The field '%s' must contain a valid IP address or domain name."), $name);
202 d799787e Matthew Grooms
	return false;
203 8dc3ef67 Scott Ullrich
}
204
205
function openvpn_validate_port($value, $name) {
206
	$value = trim($value);
207 3e2bd5de Ermal Lu?i
	if (empty($value) || !is_numeric($value) || $value < 0 || ($value > 65535))
208 4aa02281 Carlos Eduardo Ramos
		return sprintf(gettext("The field '%s' must contain a valid port, ranging from 0 to 65535."), $name);
209 b398bbca Martin Fuchs
	return false;
210 8dc3ef67 Scott Ullrich
}
211
212
function openvpn_validate_cidr($value, $name) {
213
	$value = trim($value);
214
	if (!empty($value)) {
215
		list($ip, $mask) = explode('/', $value);
216
		if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
217 4aa02281 Carlos Eduardo Ramos
			return sprintf(gettext("The field '%s' must contain a valid CIDR range."), $name);
218 8dc3ef67 Scott Ullrich
	}
219
	return false;
220 afb07cf1 Scott Ullrich
}
221
222 d799787e Matthew Grooms
function openvpn_add_dhcpopts(& $settings, & $conf) {
223 afb07cf1 Scott Ullrich
224 d799787e Matthew Grooms
	if (!empty($settings['dns_domain'])) 
225
		$conf .= "push \"dhcp-option DOMAIN {$settings['dns_domain']}\"\n";
226 add2e3f7 Scott Ullrich
227 d799787e Matthew Grooms
	if (!empty($settings['dns_server1']))
228
		$conf .= "push \"dhcp-option DNS {$settings['dns_server1']}\"\n";
229
	if (!empty($settings['dns_server2']))
230
		$conf .= "push \"dhcp-option DNS {$settings['dns_server2']}\"\n";
231
	if (!empty($settings['dns_server3']))
232
		$conf .= "push \"dhcp-option DNS {$settings['dns_server3']}\"\n";
233
	if (!empty($settings['dns_server4']))
234
		$conf .= "push \"dhcp-option DNS {$settings['dns_server4']}\"\n";
235 f9927473 Scott Ullrich
236 d799787e Matthew Grooms
	if (!empty($settings['ntp_server1']))
237 c7f70dbc Chris Buechler
		$conf .= "push \"dhcp-option NTP {$settings['ntp_server1']}\"\n";
238 d799787e Matthew Grooms
	if (!empty($settings['ntp_server2']))
239 c7f70dbc Chris Buechler
		$conf .= "push \"dhcp-option NTP {$settings['ntp_server2']}\"\n";
240 f9927473 Scott Ullrich
241 d799787e Matthew Grooms
	if ($settings['netbios_enable']) {
242 add2e3f7 Scott Ullrich
243 095a95ae Matthew Grooms
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0))
244
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
245
		if (!empty($settings['dhcp_nbtscope'])) 
246 d799787e Matthew Grooms
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
247 8dc3ef67 Scott Ullrich
248 d799787e Matthew Grooms
		if (!empty($settings['wins_server1']))
249
			$conf .= "push \"dhcp-option WINS {$settings['wins_server1']}\"\n";
250
		if (!empty($settings['wins_server2']))
251
			$conf .= "push \"dhcp-option WINS {$settings['wins_server2']}\"\n";
252 add2e3f7 Scott Ullrich
253 d799787e Matthew Grooms
		if (!empty($settings['nbdd_server1']))
254
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server1']}\"\n";
255
	}
256 8dc3ef67 Scott Ullrich
257 d799787e Matthew Grooms
	if ($settings['gwredir']) 
258
		$conf .= "push \"redirect-gateway def1\"\n";
259
}
260 24012690 Scott Ullrich
261 d799787e Matthew Grooms
function openvpn_add_custom(& $settings, & $conf) {
262 add2e3f7 Scott Ullrich
263 d799787e Matthew Grooms
	if ($settings['custom_options']) {
264 8dc3ef67 Scott Ullrich
265 d799787e Matthew Grooms
		$options = explode(';', $settings['custom_options']);
266
267
		if (is_array($options)) {
268
			foreach ($options as $option)
269
				$conf .= "$option\n";
270
		} else
271
			$conf .= "{$settings['custom_options']}\n";
272 add2e3f7 Scott Ullrich
	}
273
}
274
275 691fbf14 Ermal Lu?i
function openvpn_add_keyfile(& $data, & $conf, $mode_id, $directive, $opt = "") {
276 d799787e Matthew Grooms
	global $g;
277 add2e3f7 Scott Ullrich
278 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.{$directive}";
279 a8f538a8 jim-p
	openvpn_create_dirs();
280 d799787e Matthew Grooms
	file_put_contents($fpath, base64_decode($data));
281 f9ac3784 Ermal Lu?i
	//chown($fpath, 'nobody');
282
	//chgrp($fpath, 'nobody');
283 6f27412f Ermal Lu?i
	@chmod($fpath, 0600);
284 d799787e Matthew Grooms
285 691fbf14 Ermal Lu?i
	$conf .= "{$directive} {$fpath} {$opt}\n";
286 4eefa6e8 Scott Ullrich
}
287
288 fc05822b jim-p
function openvpn_reconfigure($mode, $settings) {
289 add2e3f7 Scott Ullrich
	global $g, $config;
290 afb07cf1 Scott Ullrich
291 93a0a028 Ermal Luçi
	if (empty($settings))
292
		return;
293 a1cab2c7 Ermal
	if (isset($settings['disable'])) 
294 4eefa6e8 Scott Ullrich
		return;
295 a8f538a8 jim-p
	openvpn_create_dirs();
296 fdd725f0 Ermal Luçi
	/*
297 d799787e Matthew Grooms
	 * NOTE: Deleting tap devices causes spontaneous reboots. Instead,
298
	 * we use a vpnid number which is allocated for a particular client
299
	 * or server configuration. ( see openvpn_vpnid_next() )
300 fdd725f0 Ermal Luçi
	 */
301 8874c692 Ermal Luçi
302 d799787e Matthew Grooms
	$vpnid = $settings['vpnid'];
303
	$mode_id = $mode.$vpnid;
304 8874c692 Ermal Luçi
305 4936ff53 jim-p
	if (isset($settings['dev_mode']))
306
		$tunname = "{$settings['dev_mode']}{$vpnid}";
307 bd7ca506 jim-p
	else {	/* defaults to tun */
308
		$tunname = "tun{$vpnid}";
309 4936ff53 jim-p
		$settings['dev_mode'] = "tun";
310 691fbf14 Ermal Lu?i
	}
311
312 bd7ca506 jim-p
	if ($mode == "server")
313
		$devname = "ovpns{$vpnid}";
314
	else
315
		$devname = "ovpnc{$vpnid}";
316 8874c692 Ermal Luçi
317 bd7ca506 jim-p
	/* is our device already configured */
318 1bc783b6 bcyrill
	if (mwexec("/sbin/ifconfig {$devname}", true)) {
319 dc408939 Matthew Grooms
320 bd7ca506 jim-p
		/* create the tap device if required */
321
		if (!file_exists("/dev/{$tunname}"))
322
			exec("/sbin/ifconfig {$tunname} create");
323 98872d89 Ermal Luçi
324 bd7ca506 jim-p
		/* rename the device */
325
		mwexec("/sbin/ifconfig {$tunname} name {$devname}");
326 095a95ae Matthew Grooms
327 bd7ca506 jim-p
		/* add the device to the openvpn group */
328
		mwexec("/sbin/ifconfig {$devname} group openvpn");
329 dc408939 Matthew Grooms
	}
330 d799787e Matthew Grooms
331 dc408939 Matthew Grooms
	$pfile = $g['varrun_path'] . "/openvpn_{$mode_id}.pid";
332 6714bbdc jim-p
	$proto = strtolower($settings['protocol']);
333
	if (substr($settings['protocol'], 0, 3) == "TCP")
334
			$proto = "{$proto}-{$mode}";
335 4936ff53 jim-p
	$dev_mode = $settings['dev_mode'];
336 c0cf27aa Scott Ullrich
	$cipher = $settings['crypto'];
337 d799787e Matthew Grooms
338 47c48e28 smos
	$interface = get_failover_interface($settings['interface']);
339 d7a0c22a bcyrill
	$ipaddr = $settings['ipaddr'];
340
	$ipaddrv6 = $settings['ipaddrv6'];
341 d799787e Matthew Grooms
342 67b0902f pierrepomes
	// If a specific ip address (VIP) is requested, use it.
343
	// Otherwise, if a specific interface is requested, use it
344
	// If "any" interface was selected, local directive will be ommited.
345 97ffc513 Seth Mos
	if (is_ipaddrv4($ipaddr)) {
346 67b0902f pierrepomes
		$iface_ip=$ipaddr;
347 3d06e8f0 pierrepomes
	} else {
348 67b0902f pierrepomes
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
349 507af8dd pierrepomes
			$iface_ip=get_interface_ip($interface);
350 67b0902f pierrepomes
		}
351 47c48e28 smos
	}
352
	if (is_ipaddrv6($ipaddrv6)) {
353
		$iface_ipv6=$ipaddrv6;
354
	} else {
355 97ffc513 Seth Mos
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
356
			$iface_ipv6=get_interface_ipv6($interface);
357
		}
358 3d06e8f0 pierrepomes
	}
359 d799787e Matthew Grooms
360 bd7ca506 jim-p
	$conf  = "dev {$devname}\n";
361 4936ff53 jim-p
	$conf .= "dev-type {$settings['dev_mode']}\n";
362 97ffc513 Seth Mos
	switch($settings['dev_mode']) {
363
		case "tun":
364
			$conf .= "tun-ipv6\n";
365
			break;
366
	}
367 bd7ca506 jim-p
	$conf .= "dev-node /dev/{$tunname}\n";
368 3c11bd3c Matthew Grooms
	$conf .= "writepid {$pfile}\n";
369
	$conf .= "#user nobody\n";
370
	$conf .= "#group nobody\n";
371 d1014c18 Chris Buechler
	$conf .= "script-security 3\n";
372 3c11bd3c Matthew Grooms
	$conf .= "daemon\n";
373
	$conf .= "keepalive 10 60\n";
374
	$conf .= "ping-timer-rem\n";
375
	$conf .= "persist-tun\n";
376
	$conf .= "persist-key\n";
377
	$conf .= "proto {$proto}\n";
378
	$conf .= "cipher {$cipher}\n";
379 8d964cea Ermal
	$conf .= "up /usr/local/sbin/ovpn-linkup\n";
380
	$conf .= "down /usr/local/sbin/ovpn-linkdown\n";
381 1492e02c Ermal
	if (file_exists("/usr/local/sbin/openvpn.attributes.sh")) {
382 a1b9105b jim-p
		switch($settings['mode']) {
383
			case 'server_user':
384
			case 'server_tls_user':
385
				$conf .= "client-connect /usr/local/sbin/openvpn.attributes.sh\n";
386
				$conf .= "client-disconnect /usr/local/sbin/openvpn.attributes.sh\n";
387
				break;
388
		}
389 1492e02c Ermal
	}
390 3c11bd3c Matthew Grooms
391 6714bbdc jim-p
	/* Determine the local IP to use - and make sure it matches with the selected protocol. */
392
	if (is_ipaddrv4($iface_ip) && (stristr($settings['protocol'], "6") === false)) {
393
		$conf .= "local {$iface_ip}\n";
394
	} elseif (is_ipaddrv6($iface_ipv6) && (stristr($settings['protocol'], "6") !== false)) {
395
		$conf .= "local {$iface_ipv6}\n";
396 97ffc513 Seth Mos
	}
397 d799787e Matthew Grooms
398 582c58ae jim-p
	if (openvpn_validate_engine($settings['engine']) && ($settings['engine'] != "none"))
399
		$conf .= "engine {$settings['engine']}\n";
400
401 67b0902f pierrepomes
	// server specific settings
402 8dc3ef67 Scott Ullrich
	if ($mode == 'server') {
403 d799787e Matthew Grooms
404 5dc6c910 jim-p
		list($ip, $cidr) = explode('/', $settings['tunnel_network']);
405 97ffc513 Seth Mos
		list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
406 5dc6c910 jim-p
		$mask = gen_subnet_mask($cidr);
407 8dc3ef67 Scott Ullrich
408 3c11bd3c Matthew Grooms
		// configure tls modes
409
		switch($settings['mode']) {
410
			case 'p2p_tls':
411
			case 'server_tls':
412 e62e2f8b Ermal Lu?i
			case 'server_user':
413 3c11bd3c Matthew Grooms
			case 'server_tls_user':
414 d799787e Matthew Grooms
				$conf .= "tls-server\n";
415 3c11bd3c Matthew Grooms
				break;
416 8dc3ef67 Scott Ullrich
		}
417 d799787e Matthew Grooms
418 3c11bd3c Matthew Grooms
		// configure p2p/server modes
419
		switch($settings['mode']) {
420 6c9cf466 jim-p
			case 'p2p_tls':
421 5dc6c910 jim-p
				// If the CIDR is less than a /30, OpenVPN will complain if you try to
422
				//  use the server directive. It works for a single client without it.
423
				//  See ticket #1417
424 74a556a3 jim-p
				if (!empty($ip) && !empty($mask) && ($cidr < 30)) {
425 5dc6c910 jim-p
					$conf .= "server {$ip} {$mask}\n";
426
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
427 a0e3ee98 jim-p
					if(is_ipaddr($ipv6))
428
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
429 5dc6c910 jim-p
				}
430 3c11bd3c Matthew Grooms
			case 'p2p_shared_key':
431 74a556a3 jim-p
				if (!empty($ip) && !empty($mask)) {
432 91c44185 jim-p
					list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
433 459e9333 jim-p
					if ($settings['dev_mode'] == 'tun')
434
						$conf .= "ifconfig {$ip1} {$ip2}\n";
435
					else
436
						$conf .= "ifconfig {$ip1} {$mask}\n";
437 1ab6bdb5 jim-p
				}
438 a0e3ee98 jim-p
				if (!empty($ipv6) && !empty($prefix)) {
439 91c44185 jim-p
					list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
440 a0e3ee98 jim-p
					if ($settings['dev_mode'] == 'tun')
441
						$conf .= "ifconfig-ipv6 {$ipv6_1} {$ipv6_2}\n";
442
					else
443
						$conf .= "ifconfig {$ipv6_1} {$prefix}\n";
444
				}
445 3c11bd3c Matthew Grooms
				break;
446
			case 'server_tls':
447
			case 'server_user':
448
			case 'server_tls_user':
449 74a556a3 jim-p
				if (!empty($ip) && !empty($mask)) {
450 1ab6bdb5 jim-p
					$conf .= "server {$ip} {$mask}\n";
451
					if(is_ipaddr($ipv6))
452
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
453
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
454
				} else {
455
					if ($settings['serverbridge_dhcp']) {
456
						if ((!empty($settings['serverbridge_interface'])) && (strcmp($settings['serverbridge_interface'], "none"))) {
457
							$biface_ip=get_interface_ip($settings['serverbridge_interface']);
458
							$biface_sm=gen_subnet_mask(get_interface_subnet($settings['serverbridge_interface']));
459
							if (is_ipaddrv4($biface_ip) && is_ipaddrv4($settings['serverbridge_dhcp_start']) && is_ipaddrv4($settings['serverbridge_dhcp_end'])) {
460
								$conf .= "server-bridge {$biface_ip} {$biface_sm} {$settings['serverbridge_dhcp_start']} {$settings['serverbridge_dhcp_end']}\n";
461
							} else {
462
								$conf .= "mode server\n";
463
							}
464
						} else {
465
							$conf .= "mode server\n";
466
						}
467
					}
468
				}
469 3c11bd3c Matthew Grooms
				break;
470 8dc3ef67 Scott Ullrich
		}
471
472 3c11bd3c Matthew Grooms
		// configure user auth modes
473
		switch($settings['mode']) {
474
			case 'server_user':
475
				$conf .= "client-cert-not-required\n";
476
			case 'server_tls_user':
477 9eced774 jim-p
				/* username-as-common-name is not compatible with server-bridge */
478
				if (stristr($conf, "server-bridge") === false)
479
					$conf .= "username-as-common-name\n";
480 8a47c190 Ermal Lu?i
				if (!empty($settings['authmode'])) {
481
					$authcfgs = explode(",", $settings['authmode']);
482
					$sed = "\$authmodes=array(";
483
					$firstsed = 0;
484
					foreach ($authcfgs as $authcfg) {
485
						if ($firstsed > 0)
486
							$sed .= ",";
487
						$firstsed = 1;
488
						$sed .= "\"{$authcfg}\"";
489
					}
490 8901958c jim-p
					$sed .= ");\\\n";
491 53d41b68 Erik Fonnesbeck
					if ($settings['strictusercn'])
492 befad728 Ermal
						$sed .= "\$strictusercn = true;";
493 1bab0df1 jim-p
					$sed .= " \$modeid = \"{$mode_id}\";";
494 8a47c190 Ermal Lu?i
					mwexec("/bin/cat /etc/inc/openvpn.auth-user.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/openvpn/{$mode_id}.php");
495
					mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.php");
496
					$conf .= "auth-user-pass-verify {$g['varetc_path']}/openvpn/{$mode_id}.php via-env\n";
497 e8a58de4 Ermal Lu?i
				}
498 3c11bd3c Matthew Grooms
				break;
499 8dc3ef67 Scott Ullrich
		}
500 41936acc jim-p
		if (!isset($settings['cert_depth']) && (strstr($settings['mode'], 'tls')))
501
			$settings['cert_depth'] = 1;
502 98963f27 jim-p
		if (is_numeric($settings['cert_depth'])) {
503
			$sed = "";
504
			$cert = lookup_cert($settings['certref']);
505
			$servercn = cert_get_cn($cert['crt']);
506
			$sed .= "\$server_cn = \"{$servercn}\";\\\n";
507
			$sed .= "\$allowed_depth = {$settings['cert_depth']};\\\n";
508
			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");
509
			mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php");
510
			$conf .= "tls-verify {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php\n";
511
		}
512 8dc3ef67 Scott Ullrich
513 63084885 Matthew Grooms
		// The local port to listen on
514 d799787e Matthew Grooms
		$conf .= "lport {$settings['local_port']}\n";
515 c0cf27aa Scott Ullrich
516 63084885 Matthew Grooms
		// The management port to listen on
517 71ca2cb2 Ermal
		// Use unix socket to overcome the problem on any type of server
518
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
519
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
520 63084885 Matthew Grooms
521 3c11bd3c Matthew Grooms
		if ($settings['maxclients'])
522 d799787e Matthew Grooms
			$conf .= "max-clients {$settings['maxclients']}\n";
523
524 3c11bd3c Matthew Grooms
		// Can we push routes
525
		if ($settings['local_network']) {
526
			list($ip, $mask) = explode('/', $settings['local_network']);
527
			$mask = gen_subnet_mask($mask);
528
			$conf .= "push \"route $ip $mask\"\n";
529
		}
530 787de45a Seth Mos
		if ($settings['local_networkv6']) {
531
			list($ipv6, $prefix) = explode('/', $settings['local_networkv6']);
532 4856df9b jim-p
			if (empty($prefix))
533
				$prefix = "128";
534 787de45a Seth Mos
			$conf .= "push \"route-ipv6 $ipv6/$prefix\"\n";
535
		}
536 3c11bd3c Matthew Grooms
537
		switch($settings['mode']) {
538
			case 'server_tls':
539
			case 'server_user':
540
			case 'server_tls_user':
541 5d8cd81a jim-p
				// Configure client dhcp options
542 3c11bd3c Matthew Grooms
				openvpn_add_dhcpopts($settings, $conf);
543 5d8cd81a jim-p
				if ($settings['client2client'])
544
					$conf .= "client-to-client\n";
545 3c11bd3c Matthew Grooms
				break;
546
		}
547 bca35cff jim-p
		if (isset($settings['duplicate_cn']))
548
			$conf .= "duplicate-cn\n";
549 d799787e Matthew Grooms
	}
550
551 3c11bd3c Matthew Grooms
	// client specific settings
552 d799787e Matthew Grooms
553 3c11bd3c Matthew Grooms
	if ($mode == 'client') {
554 d799787e Matthew Grooms
555 3c11bd3c Matthew Grooms
		// configure p2p mode
556
		switch($settings['mode']) {
557
			case 'p2p_tls':
558
				$conf .= "tls-client\n";
559
			case 'shared_key':
560
				$conf .= "client\n";
561
				break;
562
		}
563 d799787e Matthew Grooms
564 e3924384 jim-p
		// If there is no bind option at all (ip and/or port), add "nobind" directive
565
		//  Otherwise, use the local port if defined, failing that, use lport 0 to 
566
		//  ensure a random source port.
567
		if ((empty($iface_ip)) && (!$settings['local_port']))
568
			$conf .= "nobind\n";
569
		elseif ($settings['local_port'])
570
			$conf .= "lport {$settings['local_port']}\n";
571
		else
572
			$conf .= "lport 0\n";
573 5708241f jim-p
574 4b887ef4 jim-p
		// Use unix socket to overcome the problem on any type of server
575
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
576 48a458d2 pierrepomes
577 3c11bd3c Matthew Grooms
		// The remote server
578
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
579
580 d799787e Matthew Grooms
		if (!empty($settings['use_shaper']))
581
			$conf .= "shaper {$settings['use_shaper']}\n";
582 ee506044 Scott Ullrich
583 d799787e Matthew Grooms
		if (!empty($settings['tunnel_network'])) {
584
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
585 8dc3ef67 Scott Ullrich
			$mask = gen_subnet_mask($mask);
586 91c44185 jim-p
			list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
587 459e9333 jim-p
			if ($settings['dev_mode'] == 'tun')
588
				$conf .= "ifconfig {$ip2} {$ip1}\n";
589
			else
590
				$conf .= "ifconfig {$ip2} {$mask}\n";
591 8dc3ef67 Scott Ullrich
		}
592 d799787e Matthew Grooms
593 a0e3ee98 jim-p
		if (!empty($settings['tunnel_networkv6'])) {
594
			list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
595 91c44185 jim-p
			list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix);
596 a0e3ee98 jim-p
			if ($settings['dev_mode'] == 'tun')
597
				$conf .= "ifconfig-ipv6 {$ipv6_2} {$ipv6_1}\n";
598
			else
599
				$conf .= "ifconfig {$ipv6_2} {$prefix}\n";
600
		}
601
602 762a24a3 Ermal Lu?i
		if ($settings['proxy_addr']) {
603
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
604
			if ($settings['proxy_authtype'] != "none") {
605
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
606
				$proxypas = "{$settings['proxy_user']}\n";
607
				$proxypas .= "{$settings['proxy_passwd']}\n";
608
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
609
			}
610
			$conf .= " \n";
611
		}
612 8dc3ef67 Scott Ullrich
	}
613
614 17c98ba9 jim-p
	// Add a remote network route if set, and only for p2p modes.
615
	if ((substr($settings['mode'], 0, 3) == "p2p") && is_subnet($settings['remote_network'])) {
616 8dc3ef67 Scott Ullrich
		list($ip, $mask) = explode('/', $settings['remote_network']);
617
		$mask = gen_subnet_mask($mask);
618 d799787e Matthew Grooms
		$conf .= "route $ip $mask\n";
619 8dc3ef67 Scott Ullrich
	}
620 4856df9b jim-p
	// Add a remote network route if set, and only for p2p modes.
621
	if ((substr($settings['mode'], 0, 3) == "p2p") && is_subnet($settings['remote_networkv6'])) {
622
		list($ipv6, $prefix) = explode('/', $settings['remote_networkv6']);
623
		if (empty($prefix))
624
			$prefix = "128";
625
		$conf .= "route-ipv6 ${ipv6}/${prefix}\n";
626
	}
627 afb07cf1 Scott Ullrich
628 d799787e Matthew Grooms
	// Write the settings for the keys
629 3c11bd3c Matthew Grooms
	switch($settings['mode']) {
630
		case 'p2p_shared_key':
631
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
632
			break;
633
		case 'p2p_tls':
634
		case 'server_tls':
635
		case 'server_tls_user':
636 e62e2f8b Ermal Lu?i
		case 'server_user':
637 3c11bd3c Matthew Grooms
			$ca = lookup_ca($settings['caref']);
638
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
639
			$cert = lookup_cert($settings['certref']);
640
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
641
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
642
			if ($mode == 'server')
643 fe787fc7 Matthew Grooms
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
644 6db02381 jim-p
			if (!empty($settings['crlref'])) {
645
				$crl = lookup_crl($settings['crlref']);
646 cfcc6994 jim-p
				crl_update($crl);
647 6db02381 jim-p
				openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify");
648
			}
649 db746ce2 Ermal Lu?i
			if ($settings['tls']) {
650 756720e2 Pierre POMES
				if ($mode == "server") 
651 db746ce2 Ermal Lu?i
					$tlsopt = 0;
652
				else
653
					$tlsopt = 1;
654
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
655
			}
656 3c11bd3c Matthew Grooms
			break;
657 8dc3ef67 Scott Ullrich
	}
658
659 1cb0b40a Matthew Grooms
	if ($settings['compression'])
660 d799787e Matthew Grooms
		$conf .= "comp-lzo\n";
661
662
	if ($settings['passtos'])
663
		$conf .= "passtos\n";
664
665
	if ($settings['resolve_retry'])
666
		$conf .= "resolv-retry infinite\n";
667
668
	if ($settings['dynamic_ip']) {
669
		$conf .= "persist-remote-ip\n";
670
		$conf .= "float\n";
671 8dc3ef67 Scott Ullrich
	}
672 afb07cf1 Scott Ullrich
673 ee55ce7d jim-p
	if ($settings['topology_subnet']) {
674
		$conf .= "topology subnet\n";
675
	}
676
677 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
678
679 a8f538a8 jim-p
	openvpn_create_dirs();
680 938fc5b0 Ermal
	$fpath = "{$g['varetc_path']}/openvpn/{$mode_id}.conf";
681 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
682 938fc5b0 Ermal
	unset($conf);
683 f9ac3784 Ermal Lu?i
	//chown($fpath, 'nobody');
684
	//chgrp($fpath, 'nobody');
685 6f27412f Ermal Lu?i
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
686
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
687
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
688
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
689 d799787e Matthew Grooms
}
690
691 fc05822b jim-p
function openvpn_restart($mode, $settings) {
692 d799787e Matthew Grooms
	global $g, $config;
693
694
	$vpnid = $settings['vpnid'];
695
	$mode_id = $mode.$vpnid;
696
697 76369bfc Matthew Grooms
	/* kill the process if running */
698 705c8ec9 Matthew Grooms
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
699 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
700 705c8ec9 Matthew Grooms
701 76369bfc Matthew Grooms
		/* read the pid file */
702
		$pid = rtrim(file_get_contents($pfile));
703
		unlink($pfile);
704 705c8ec9 Matthew Grooms
705 76369bfc Matthew Grooms
		/* send a term signal to the process */
706
		posix_kill($pid, SIGTERM);
707
708
		/* wait until the process exits */
709
		while(posix_kill($pid, 0))
710
			usleep(250000);
711
	}
712 d799787e Matthew Grooms
713 a1cab2c7 Ermal
	if (isset($settings['disable']))
714 d799787e Matthew Grooms
		return;
715
716 260f267e jim-p
	/* Do not start a client if we are a CARP backup on this vip! */
717
	if (($mode == "client") && strstr($settings['interface'], "_vip") && (get_carp_interface_status($settings['interface']) == "BACKUP"))
718 9ea0cb90 jim-p
		return;
719
720 705c8ec9 Matthew Grooms
	/* start the new process */
721 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
722 91c44185 jim-p
	openvpn_clear_route($mode, $settings);
723 5a7cc1f9 Ermal
	mwexec_bg("/usr/local/sbin/openvpn --config {$fpath}");
724 847cd48d Ermal
725
	if (!$g['booting'])
726
		send_event("filter reload");
727 afb07cf1 Scott Ullrich
}
728
729 dc408939 Matthew Grooms
function openvpn_delete($mode, & $settings) {
730 d799787e Matthew Grooms
	global $g, $config;
731
732
	$vpnid = $settings['vpnid'];
733
	$mode_id = $mode.$vpnid;
734
735 da601f8e PiBa-NL
	if (isset($settings['dev_mode']))
736
		$tunname = "{$settings['dev_mode']}{$vpnid}";
737
	else {  /* defaults to tun */
738
		$tunname = "tun{$vpnid}";
739
	}
740
741 095a95ae Matthew Grooms
	if ($mode == "server")
742
		$devname = "ovpns{$vpnid}";
743
	else
744
		$devname = "ovpnc{$vpnid}";
745 dc408939 Matthew Grooms
746 76369bfc Matthew Grooms
	/* kill the process if running */
747 dc408939 Matthew Grooms
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
748 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
749 dc408939 Matthew Grooms
750 76369bfc Matthew Grooms
		/* read the pid file */
751
		$pid = trim(file_get_contents($pfile));
752
		unlink($pfile);
753
754
		/* send a term signal to the process */
755
		posix_kill($pid, SIGTERM);
756
	}
757 705c8ec9 Matthew Grooms
758 095a95ae Matthew Grooms
	/* remove the device from the openvpn group */
759
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
760
761 dc408939 Matthew Grooms
	/* restore the original adapter name */
762
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
763
764
	/* remove the configuration files */
765
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
766 d799787e Matthew Grooms
}
767 afb07cf1 Scott Ullrich
768 dc408939 Matthew Grooms
function openvpn_resync_csc(& $settings) {
769 8dc3ef67 Scott Ullrich
	global $g, $config;
770
771 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
772 8dc3ef67 Scott Ullrich
773 a1cab2c7 Ermal
	if (isset($settings['disable'])) {
774 d799787e Matthew Grooms
		unlink_if_exists($fpath);
775 c876662c Scott Ullrich
		return;
776
	}
777 a8f538a8 jim-p
	openvpn_create_dirs();
778 d799787e Matthew Grooms
779 8dc3ef67 Scott Ullrich
	$conf = '';
780 d799787e Matthew Grooms
	if ($settings['block'])
781
		$conf .= "disable\n";
782
783
	if ($settings['push_reset'])
784
		$conf .= "push-reset\n";
785
786
	if (!empty($settings['tunnel_network'])) {
787
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
788 96033063 Erik Fonnesbeck
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
789 298fe5ae jim-p
		$serverip = long2ip32($baselong + 1);
790
		$clientip = long2ip32($baselong + 2);
791
		/* Because this is being pushed, the order from the client's point of view. */
792 d9c96fb1 jim-p
		if ($settings['dev_mode'] != 'tap')
793
			$conf .= "ifconfig-push {$clientip} {$serverip}\n";
794 e052047d jim-p
		else
795
			$conf .= "ifconfig-push {$clientip} {$mask}\n";
796 8dc3ef67 Scott Ullrich
	}
797 6d031071 Martin Fuchs
798 d799787e Matthew Grooms
	openvpn_add_dhcpopts($settings, $conf);
799 8dc3ef67 Scott Ullrich
800 d799787e Matthew Grooms
	if ($settings['gwredir'])
801
		$conf .= "push \"redirect-gateway def1\"\n";
802 6d031071 Martin Fuchs
803 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
804 8dc3ef67 Scott Ullrich
805 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
806
	chown($fpath, 'nobody');
807
	chgrp($fpath, 'nobody');
808
}
809 8dc3ef67 Scott Ullrich
810 dc408939 Matthew Grooms
function openvpn_delete_csc(& $settings) {
811 add2e3f7 Scott Ullrich
	global $g, $config;
812 3c2e5528 Scott Ullrich
813 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
814 d799787e Matthew Grooms
	unlink_if_exists($fpath);
815 267ab13f Ermal Luçi
}
816 afb07cf1 Scott Ullrich
817 24012690 Scott Ullrich
// Resync the configuration and restart the VPN
818 fc05822b jim-p
function openvpn_resync($mode, $settings) {
819 dc408939 Matthew Grooms
	openvpn_reconfigure($mode, $settings);
820
	openvpn_restart($mode, $settings);
821 afb07cf1 Scott Ullrich
}
822
823 add2e3f7 Scott Ullrich
// Resync and restart all VPNs
824 c7f60193 Ermal
function openvpn_resync_all($interface = "") {
825 d799787e Matthew Grooms
	global $g, $config;
826 267ab13f Ermal Luçi
827 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
828
		return;
829 a8f538a8 jim-p
	openvpn_create_dirs();
830 3cb54b54 Matthew Grooms
831 34bc1324 Matthew Grooms
	if (!is_array($config['openvpn']))
832
		$config['openvpn'] = array();
833
834 15b414e6 Matthew Grooms
/*
835 34bc1324 Matthew Grooms
	if (!$config['openvpn']['dh-parameters']) {
836
		echo "Configuring OpenVPN Parameters ...\n";
837 035e4289 Matthew Grooms
		$dh_parameters = openvpn_create_dhparams(1024);
838 34bc1324 Matthew Grooms
		$dh_parameters = base64_encode($dh_parameters);
839
		$config['openvpn']['dh-parameters'] = $dh_parameters;
840 c67dd94e Bill Marquette
		write_config("OpenVPN DH parameters");
841 34bc1324 Matthew Grooms
	}
842
843
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
844
	if (!file_exists($path_ovdh)) {
845
		$dh_parameters = $config['openvpn']['dh-parameters'];
846
		$dh_parameters = base64_decode($dh_parameters);
847
		file_put_contents($path_ovdh, $dh_parameters);
848
	}
849 15b414e6 Matthew Grooms
*/
850 739c9efd Ermal
	if ($interface <> "")
851 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances for interface " . convert_friendly_interface_to_friendly_descr($interface) . ".");
852 739c9efd Ermal
	else
853 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances."); 
854 34bc1324 Matthew Grooms
855 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-server'])) {
856
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
857 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
858 c7f60193 Ermal
				continue;
859 dc408939 Matthew Grooms
			openvpn_resync('server', $settings);
860 c7f60193 Ermal
		}
861
	}
862 5b237745 Scott Ullrich
863 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-client'])) {
864
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
865 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
866 c7f60193 Ermal
				continue;
867 dc408939 Matthew Grooms
			openvpn_resync('client', $settings);
868 c7f60193 Ermal
		}
869
	}
870 afb07cf1 Scott Ullrich
871 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-csc']))
872 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
873
			openvpn_resync_csc($settings);
874 afb07cf1 Scott Ullrich
875 5b237745 Scott Ullrich
}
876 702a4702 Scott Ullrich
877 453d9c96 jim-p
function openvpn_get_active_servers($type="multipoint") {
878 71ca2cb2 Ermal
	global $config, $g;
879
880 53663f57 jim-p
	$servers = array();
881
	if (is_array($config['openvpn']['openvpn-server'])) {
882
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
883 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
884
				continue;
885
886 53663f57 jim-p
			$prot = $settings['protocol'];
887
			$port = $settings['local_port'];
888
	
889
			$server = array();
890 95305736 jim-p
			$server['port'] = ($settings['local_port']) ? $settings['local_port'] : 1194;
891 41be629f jim-p
			$server['mode'] = $settings['mode'];
892 53663f57 jim-p
			if ($settings['description'])
893
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
894
			else
895
				$server['name'] = "Server {$prot}:{$port}";
896
			$server['conns'] = array();
897
	
898 71ca2cb2 Ermal
			$vpnid = $settings['vpnid'];
899 95305736 jim-p
			$mode_id = "server{$vpnid}";
900 71ca2cb2 Ermal
			$server['mgmt'] = $mode_id;
901 95305736 jim-p
			$socket = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
902 453d9c96 jim-p
			list($tn, $sm) = explode('/', $settings['tunnel_network']);
903
904
			if ((($server['mode'] == "p2p_shared_key") || ($sm >= 30) ) && ($type == "p2p"))
905 95305736 jim-p
				$servers[] = openvpn_get_client_status($server, $socket);
906 453d9c96 jim-p
			elseif (($server['mode'] != "p2p_shared_key") && ($type == "multipoint") && ($sm < 30))
907 95305736 jim-p
				$servers[] = openvpn_get_server_status($server, $socket);
908 453d9c96 jim-p
909 95305736 jim-p
		}
910
	}
911
	return $servers;
912
}
913 b0140675 Ermal
914 95305736 jim-p
function openvpn_get_server_status($server, $socket) {
915
	$errval;
916
	$errstr;
917
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
918
	if ($fp) {
919
		stream_set_timeout($fp, 1);
920
921
		/* send our status request */
922
		fputs($fp, "status 2\n");
923
924
		/* recv all response lines */
925
		while (!feof($fp)) {
926
927
			/* read the next line */
928
			$line = fgets($fp, 1024);
929
930
			$info = stream_get_meta_data($fp);
931
			if ($info['timed_out'])
932
				break;
933
934
			/* parse header list line */
935
			if (strstr($line, "HEADER"))
936
				continue;
937
938
			/* parse end of output line */
939
			if (strstr($line, "END") || strstr($line, "ERROR"))
940
				break;
941
942
			/* parse client list line */
943
			if (strstr($line, "CLIENT_LIST")) {
944
				$list = explode(",", $line);
945 53663f57 jim-p
				$conn = array();
946 95305736 jim-p
				$conn['common_name'] = $list[1];
947
				$conn['remote_host'] = $list[2];
948
				$conn['virtual_addr'] = $list[3];
949
				$conn['bytes_recv'] = $list[4];
950
				$conn['bytes_sent'] = $list[5];
951
				$conn['connect_time'] = $list[6];
952 53663f57 jim-p
				$server['conns'][] = $conn;
953
			}
954 ec970b50 jim-p
			/* parse routing table lines */
955
			if (strstr($line, "ROUTING_TABLE")) {
956
				$list = explode(",", $line);
957
				$conn = array();
958
				$conn['virtual_addr'] = $list[1];
959
				$conn['common_name'] = $list[2];
960
				$conn['remote_host'] = $list[3];
961
				$conn['last_time'] = $list[4];
962
				$server['routes'][] = $conn;
963
			}
964 53663f57 jim-p
		}
965 95305736 jim-p
966
		/* cleanup */
967
		fclose($fp);
968
	} else {
969
		$conn = array();
970
		$conn['common_name'] = "[error]";
971
		$conn['remote_host'] = "Management Daemon Unreachable";
972
		$conn['virtual_addr'] = "";
973
		$conn['bytes_recv'] = 0;
974
		$conn['bytes_sent'] = 0;
975
		$conn['connect_time'] = 0;
976
		$server['conns'][] = $conn;
977 53663f57 jim-p
	}
978 95305736 jim-p
	return $server;
979 53663f57 jim-p
}
980
981
function openvpn_get_active_clients() {
982 71ca2cb2 Ermal
	global $config, $g;
983
984 53663f57 jim-p
	$clients = array();
985
	if (is_array($config['openvpn']['openvpn-client'])) {
986
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
987
	
988 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
989
				continue;
990
991 53663f57 jim-p
			$prot = $settings['protocol'];
992 95305736 jim-p
			$port = ($settings['local_port']) ? ":{$settings['local_port']}" : "";
993 53663f57 jim-p
	
994
			$client = array();
995
			$client['port'] = $settings['local_port'];
996
			if ($settings['description'])
997 95305736 jim-p
				$client['name'] = "{$settings['description']} {$prot}{$port}";
998 53663f57 jim-p
			else
999 95305736 jim-p
				$client['name'] = "Client {$prot}{$port}";
1000 53663f57 jim-p
	
1001 71ca2cb2 Ermal
			$vpnid = $settings['vpnid'];
1002 95305736 jim-p
			$mode_id = "client{$vpnid}";
1003 71ca2cb2 Ermal
			$client['mgmt'] = $mode_id;
1004 95305736 jim-p
			$socket = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
1005 53663f57 jim-p
			$client['status']="down";
1006 95305736 jim-p
1007
			$clients[] = openvpn_get_client_status($client, $socket);
1008
		}
1009
	}
1010
	return $clients;
1011
}
1012
1013
function openvpn_get_client_status($client, $socket) {
1014
	$errval;
1015
	$errstr;
1016
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
1017
	if ($fp) {
1018
		stream_set_timeout($fp, 1);
1019
		/* send our status request */
1020
		fputs($fp, "state 1\n");
1021
1022
		/* recv all response lines */
1023
		while (!feof($fp)) {
1024
			/* read the next line */
1025
			$line = fgets($fp, 1024);
1026
1027
			$info = stream_get_meta_data($fp);
1028
			if ($info['timed_out'])
1029
				break;
1030
1031
			/* Get the client state */
1032
			if (strstr($line,"CONNECTED")) {
1033
				$client['status']="up";
1034
				$list = explode(",", $line);
1035
1036
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1037
				$client['virtual_addr']  = $list[3];
1038
				$client['remote_host'] = $list[4];
1039
			}
1040 453d9c96 jim-p
			if (strstr($line,"CONNECTING")) {
1041
				$client['status']="connecting";
1042
			}
1043
			if (strstr($line,"ASSIGN_IP")) {
1044
				$client['status']="waiting";
1045
				$list = explode(",", $line);
1046
1047
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1048
				$client['virtual_addr']  = $list[3];
1049
			}
1050
			if (strstr($line,"RECONNECTING")) {
1051
				$client['status']="reconnecting";
1052
				$list = explode(",", $line);
1053
1054
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
1055
				$client['status'] .= "; " . $list[2];
1056
			}
1057 95305736 jim-p
			/* parse end of output line */
1058
			if (strstr($line, "END") || strstr($line, "ERROR"))
1059
				break;
1060
		}
1061
1062
		/* If up, get read/write stats */
1063
		if (strcmp($client['status'], "up") == 0) {
1064
			fputs($fp, "status 2\n");
1065
			/* recv all response lines */
1066
			while (!feof($fp)) {
1067
				/* read the next line */
1068
				$line = fgets($fp, 1024);
1069
1070
				$info = stream_get_meta_data($fp);
1071
				if ($info['timed_out'])
1072
					break;
1073
1074
				if (strstr($line,"TCP/UDP read bytes")) {
1075
					$list = explode(",", $line);
1076
					$client['bytes_recv'] = $list[1];
1077 53663f57 jim-p
				}
1078 95305736 jim-p
1079
				if (strstr($line,"TCP/UDP write bytes")) {
1080
					$list = explode(",", $line);
1081
					$client['bytes_sent'] = $list[1];
1082 53663f57 jim-p
				}
1083 95305736 jim-p
1084
				/* parse end of output line */
1085
				if (strstr($line, "END"))
1086
					break;
1087 53663f57 jim-p
			}
1088
		}
1089 95305736 jim-p
1090
		fclose($fp);
1091
1092
	} else {
1093
		$DisplayNote=true;
1094
		$client['remote_host'] = "No Management Daemon";
1095
		$client['virtual_addr'] = "See Note Below";
1096
		$client['bytes_recv'] = 0;
1097
		$client['bytes_sent'] = 0;
1098
		$client['connect_time'] = 0;
1099 53663f57 jim-p
	}
1100 95305736 jim-p
	return $client;
1101 53663f57 jim-p
}
1102 8e022a76 jim-p
1103
function openvpn_refresh_crls() {
1104
	global $g, $config;
1105
1106 a8f538a8 jim-p
	openvpn_create_dirs();
1107 8e022a76 jim-p
1108
	if (is_array($config['openvpn']['openvpn-server'])) {
1109
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1110
			if (empty($settings))
1111
				continue;
1112
			if (isset($settings['disable']))
1113
				continue;
1114
			// Write the settings for the keys
1115
			switch($settings['mode']) {
1116
				case 'p2p_tls':
1117
				case 'server_tls':
1118
				case 'server_tls_user':
1119
				case 'server_user':
1120
					if (!empty($settings['crlref'])) {
1121
						$crl = lookup_crl($settings['crlref']);
1122 728003c8 jim-p
						crl_update($crl);
1123 8e022a76 jim-p
						$fpath = $g['varetc_path']."/openvpn/server{$settings['vpnid']}.crl-verify";
1124
						file_put_contents($fpath, base64_decode($crl['text']));
1125
						@chmod($fpath, 0644);
1126
					}
1127
					break;
1128
			}
1129
		}
1130
	}
1131
}
1132
1133 a8f538a8 jim-p
function openvpn_create_dirs() {
1134
	global $g;
1135
	if (!is_dir("{$g['varetc_path']}/openvpn"))
1136
		safe_mkdir("{$g['varetc_path']}/openvpn", 0750);
1137
	if (!is_dir("{$g['varetc_path']}/openvpn-csc"))
1138
		safe_mkdir("{$g['varetc_path']}/openvpn-csc", 0750);
1139
}
1140
1141 91c44185 jim-p
function openvpn_get_interface_ip($ip, $mask) {
1142
	$baselong = ip2long32($ip) & ip2long($mask);
1143
	$ip1 = long2ip32($baselong + 1);
1144
	$ip2 = long2ip32($baselong + 2);
1145
	return array($ip1, $ip2);
1146
}
1147
1148
function openvpn_get_interface_ipv6($ipv6, $prefix) {
1149
	$basev6 = gen_subnetv6($ipv6, $prefix);
1150
	// Is there a better way to do this math?
1151
	$ipv6_arr = explode(':', $basev6);
1152
	$last = hexdec(array_pop($ipv6_arr));
1153
	$ipv6_1 = Net_IPv6::compress(implode(':', $ipv6_arr) . ':' . dechex($last + 1));
1154
	$ipv6_2 = Net_IPv6::compress(implode(':', $ipv6_arr) . ':' . dechex($last + 2));
1155
	return array($ipv6_1, $ipv6_2);
1156
}
1157
1158
function openvpn_clear_route($mode, $settings) {
1159
	if (empty($settings['tunnel_network']))
1160
		return;
1161
	list($ip, $cidr) = explode('/', $settings['tunnel_network']);
1162
	$mask = gen_subnet_mask($cidr);
1163
	switch($settings['mode']) {
1164
		case 'p2p_tls':
1165
		case 'p2p_shared_key':
1166
		case 'shared_key':
1167
			if (!empty($ip) && !empty($mask) && ($cidr == 30)) {
1168
				list($ip1, $ip2) = openvpn_get_interface_ip($ip, $mask);
1169
				$ip_to_clear = ($mode == "server") ? $ip1 : $ip2;
1170
				mwexec("/sbin/route -q delete {$ip_to_clear}");
1171
			}
1172
			break;
1173
	}
1174
}
1175
1176 756720e2 Pierre POMES
?>