Project

General

Profile

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