Project

General

Profile

Download (31.1 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
	$interface = $settings['interface'];
338 67b0902f pierrepomes
	$ipaddr = $settings['ipaddr'];
339 97ffc513 Seth Mos
	$ipaddrv6 = $settings['ipaddrv6'];
340 d799787e Matthew Grooms
341 67b0902f pierrepomes
	// If a specific ip address (VIP) is requested, use it.
342
	// Otherwise, if a specific interface is requested, use it
343
	// If "any" interface was selected, local directive will be ommited.
344 97ffc513 Seth Mos
	if (is_ipaddrv4($ipaddr)) {
345 67b0902f pierrepomes
		$iface_ip=$ipaddr;
346 97ffc513 Seth Mos
	} elseif (is_ipaddrv6($ipaddrv6)) {
347
		$iface_ipv6=$ipaddrv6;
348 3d06e8f0 pierrepomes
	} else {
349 67b0902f pierrepomes
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
350 507af8dd pierrepomes
			$iface_ip=get_interface_ip($interface);
351 67b0902f pierrepomes
		}
352 97ffc513 Seth Mos
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
353
			$iface_ipv6=get_interface_ipv6($interface);
354
		}
355 3d06e8f0 pierrepomes
	}
356 d799787e Matthew Grooms
357 bd7ca506 jim-p
	$conf  = "dev {$devname}\n";
358 4936ff53 jim-p
	$conf .= "dev-type {$settings['dev_mode']}\n";
359 97ffc513 Seth Mos
	switch($settings['dev_mode']) {
360
		case "tun":
361
			$conf .= "tun-ipv6\n";
362
			break;
363
	}
364 bd7ca506 jim-p
	$conf .= "dev-node /dev/{$tunname}\n";
365 3c11bd3c Matthew Grooms
	$conf .= "writepid {$pfile}\n";
366
	$conf .= "#user nobody\n";
367
	$conf .= "#group nobody\n";
368 d1014c18 Chris Buechler
	$conf .= "script-security 3\n";
369 3c11bd3c Matthew Grooms
	$conf .= "daemon\n";
370
	$conf .= "keepalive 10 60\n";
371
	$conf .= "ping-timer-rem\n";
372
	$conf .= "persist-tun\n";
373
	$conf .= "persist-key\n";
374
	$conf .= "proto {$proto}\n";
375
	$conf .= "cipher {$cipher}\n";
376 8d964cea Ermal
	$conf .= "up /usr/local/sbin/ovpn-linkup\n";
377
	$conf .= "down /usr/local/sbin/ovpn-linkdown\n";
378 3c11bd3c Matthew Grooms
379 97ffc513 Seth Mos
	if (is_ipaddrv4($iface_ip)) {
380 48a458d2 pierrepomes
		$conf .= "local {$iface_ip}\n";	
381 67b0902f pierrepomes
	}
382 97ffc513 Seth Mos
	if (is_ipaddrv6($iface_ipv6)) {
383
		// $conf .= "local {$iface_ipv6}\n";	
384
	}
385 d799787e Matthew Grooms
386 582c58ae jim-p
	if (openvpn_validate_engine($settings['engine']) && ($settings['engine'] != "none"))
387
		$conf .= "engine {$settings['engine']}\n";
388
389 67b0902f pierrepomes
	// server specific settings
390 8dc3ef67 Scott Ullrich
	if ($mode == 'server') {
391 d799787e Matthew Grooms
392 5dc6c910 jim-p
		list($ip, $cidr) = explode('/', $settings['tunnel_network']);
393 97ffc513 Seth Mos
		list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']);
394 5dc6c910 jim-p
		$mask = gen_subnet_mask($cidr);
395 8dc3ef67 Scott Ullrich
396 3c11bd3c Matthew Grooms
		// configure tls modes
397
		switch($settings['mode']) {
398
			case 'p2p_tls':
399
			case 'server_tls':
400 e62e2f8b Ermal Lu?i
			case 'server_user':
401 3c11bd3c Matthew Grooms
			case 'server_tls_user':
402 d799787e Matthew Grooms
				$conf .= "tls-server\n";
403 3c11bd3c Matthew Grooms
				break;
404 8dc3ef67 Scott Ullrich
		}
405 d799787e Matthew Grooms
406 3c11bd3c Matthew Grooms
		// configure p2p/server modes
407
		switch($settings['mode']) {
408 6c9cf466 jim-p
			case 'p2p_tls':
409 5dc6c910 jim-p
				// If the CIDR is less than a /30, OpenVPN will complain if you try to
410
				//  use the server directive. It works for a single client without it.
411
				//  See ticket #1417
412 74a556a3 jim-p
				if (!empty($ip) && !empty($mask) && ($cidr < 30)) {
413 5dc6c910 jim-p
					$conf .= "server {$ip} {$mask}\n";
414
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
415
				}
416 3c11bd3c Matthew Grooms
			case 'p2p_shared_key':
417 74a556a3 jim-p
				if (!empty($ip) && !empty($mask)) {
418 1ab6bdb5 jim-p
					$baselong = ip2long32($ip) & ip2long($mask);
419
					$ip1 = long2ip32($baselong + 1);
420
					$ip2 = long2ip32($baselong + 2);
421 459e9333 jim-p
					if ($settings['dev_mode'] == 'tun')
422
						$conf .= "ifconfig {$ip1} {$ip2}\n";
423
					else
424
						$conf .= "ifconfig {$ip1} {$mask}\n";
425 1ab6bdb5 jim-p
				}
426 3c11bd3c Matthew Grooms
				break;
427
			case 'server_tls':
428
			case 'server_user':
429
			case 'server_tls_user':
430 74a556a3 jim-p
				if (!empty($ip) && !empty($mask)) {
431 1ab6bdb5 jim-p
					$conf .= "server {$ip} {$mask}\n";
432
					if(is_ipaddr($ipv6))
433
						$conf .= "server-ipv6 {$ipv6}/{$prefix}\n";
434
					$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
435
				} else {
436
					if ($settings['serverbridge_dhcp']) {
437
						if ((!empty($settings['serverbridge_interface'])) && (strcmp($settings['serverbridge_interface'], "none"))) {
438
							$biface_ip=get_interface_ip($settings['serverbridge_interface']);
439
							$biface_sm=gen_subnet_mask(get_interface_subnet($settings['serverbridge_interface']));
440
							if (is_ipaddrv4($biface_ip) && is_ipaddrv4($settings['serverbridge_dhcp_start']) && is_ipaddrv4($settings['serverbridge_dhcp_end'])) {
441
								$conf .= "server-bridge {$biface_ip} {$biface_sm} {$settings['serverbridge_dhcp_start']} {$settings['serverbridge_dhcp_end']}\n";
442
							} else {
443
								$conf .= "mode server\n";
444
							}
445
						} else {
446
							$conf .= "mode server\n";
447
						}
448
					}
449
				}
450 3c11bd3c Matthew Grooms
				break;
451 8dc3ef67 Scott Ullrich
		}
452
453 3c11bd3c Matthew Grooms
		// configure user auth modes
454
		switch($settings['mode']) {
455
			case 'server_user':
456
				$conf .= "client-cert-not-required\n";
457
			case 'server_tls_user':
458 9eced774 jim-p
				/* username-as-common-name is not compatible with server-bridge */
459
				if (stristr($conf, "server-bridge") === false)
460
					$conf .= "username-as-common-name\n";
461 8a47c190 Ermal Lu?i
				if (!empty($settings['authmode'])) {
462
					$authcfgs = explode(",", $settings['authmode']);
463
					$sed = "\$authmodes=array(";
464
					$firstsed = 0;
465
					foreach ($authcfgs as $authcfg) {
466
						if ($firstsed > 0)
467
							$sed .= ",";
468
						$firstsed = 1;
469
						$sed .= "\"{$authcfg}\"";
470
					}
471 8901958c jim-p
					$sed .= ");\\\n";
472 53d41b68 Erik Fonnesbeck
					if ($settings['strictusercn'])
473 befad728 Ermal
						$sed .= "\$strictusercn = true;";
474 1bab0df1 jim-p
					$sed .= " \$modeid = \"{$mode_id}\";";
475 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");
476
					mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.php");
477
					$conf .= "auth-user-pass-verify {$g['varetc_path']}/openvpn/{$mode_id}.php via-env\n";
478 e8a58de4 Ermal Lu?i
				}
479 3c11bd3c Matthew Grooms
				break;
480 8dc3ef67 Scott Ullrich
		}
481 41936acc jim-p
		if (!isset($settings['cert_depth']) && (strstr($settings['mode'], 'tls')))
482
			$settings['cert_depth'] = 1;
483 98963f27 jim-p
		if (is_numeric($settings['cert_depth'])) {
484
			$sed = "";
485
			$cert = lookup_cert($settings['certref']);
486
			$servercn = cert_get_cn($cert['crt']);
487
			$sed .= "\$server_cn = \"{$servercn}\";\\\n";
488
			$sed .= "\$allowed_depth = {$settings['cert_depth']};\\\n";
489
			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");
490
			mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php");
491
			$conf .= "tls-verify {$g['varetc_path']}/openvpn/{$mode_id}.tls-verify.php\n";
492
		}
493 8dc3ef67 Scott Ullrich
494 63084885 Matthew Grooms
		// The local port to listen on
495 d799787e Matthew Grooms
		$conf .= "lport {$settings['local_port']}\n";
496 c0cf27aa Scott Ullrich
497 63084885 Matthew Grooms
		// The management port to listen on
498 71ca2cb2 Ermal
		// Use unix socket to overcome the problem on any type of server
499
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
500
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
501 63084885 Matthew Grooms
502 3c11bd3c Matthew Grooms
		if ($settings['maxclients'])
503 d799787e Matthew Grooms
			$conf .= "max-clients {$settings['maxclients']}\n";
504
505 3c11bd3c Matthew Grooms
		// Can we push routes
506
		if ($settings['local_network']) {
507
			list($ip, $mask) = explode('/', $settings['local_network']);
508
			$mask = gen_subnet_mask($mask);
509
			$conf .= "push \"route $ip $mask\"\n";
510
		}
511 787de45a Seth Mos
		if ($settings['local_networkv6']) {
512
			list($ipv6, $prefix) = explode('/', $settings['local_networkv6']);
513
			$conf .= "push \"route-ipv6 $ipv6/$prefix\"\n";
514
		}
515 3c11bd3c Matthew Grooms
516
		switch($settings['mode']) {
517
			case 'server_tls':
518
			case 'server_user':
519
			case 'server_tls_user':
520 5d8cd81a jim-p
				// Configure client dhcp options
521 3c11bd3c Matthew Grooms
				openvpn_add_dhcpopts($settings, $conf);
522 5d8cd81a jim-p
				if ($settings['client2client'])
523
					$conf .= "client-to-client\n";
524 3c11bd3c Matthew Grooms
				break;
525
		}
526 bca35cff jim-p
		if (isset($settings['duplicate_cn']))
527
			$conf .= "duplicate-cn\n";
528 d799787e Matthew Grooms
	}
529
530 3c11bd3c Matthew Grooms
	// client specific settings
531 d799787e Matthew Grooms
532 3c11bd3c Matthew Grooms
	if ($mode == 'client') {
533 d799787e Matthew Grooms
534 3c11bd3c Matthew Grooms
		// configure p2p mode
535
		switch($settings['mode']) {
536
			case 'p2p_tls':
537
				$conf .= "tls-client\n";
538
			case 'shared_key':
539
				$conf .= "client\n";
540
				break;
541
		}
542 d799787e Matthew Grooms
543 e3924384 jim-p
		// If there is no bind option at all (ip and/or port), add "nobind" directive
544
		//  Otherwise, use the local port if defined, failing that, use lport 0 to 
545
		//  ensure a random source port.
546
		if ((empty($iface_ip)) && (!$settings['local_port']))
547
			$conf .= "nobind\n";
548
		elseif ($settings['local_port'])
549
			$conf .= "lport {$settings['local_port']}\n";
550
		else
551
			$conf .= "lport 0\n";
552 5708241f jim-p
553 4b887ef4 jim-p
		// Use unix socket to overcome the problem on any type of server
554
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
555 48a458d2 pierrepomes
556 3c11bd3c Matthew Grooms
		// The remote server
557
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
558
559 d799787e Matthew Grooms
		if (!empty($settings['use_shaper']))
560
			$conf .= "shaper {$settings['use_shaper']}\n";
561 ee506044 Scott Ullrich
562 d799787e Matthew Grooms
		if (!empty($settings['tunnel_network'])) {
563
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
564 8dc3ef67 Scott Ullrich
			$mask = gen_subnet_mask($mask);
565 96033063 Erik Fonnesbeck
			$baselong = ip2long32($ip) & ip2long($mask);
566
			$ip1 = long2ip32($baselong + 1);
567
			$ip2 = long2ip32($baselong + 2);
568 459e9333 jim-p
			if ($settings['dev_mode'] == 'tun')
569
				$conf .= "ifconfig {$ip2} {$ip1}\n";
570
			else
571
				$conf .= "ifconfig {$ip2} {$mask}\n";
572 8dc3ef67 Scott Ullrich
		}
573 d799787e Matthew Grooms
574 762a24a3 Ermal Lu?i
		if ($settings['proxy_addr']) {
575
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
576
			if ($settings['proxy_authtype'] != "none") {
577
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
578
				$proxypas = "{$settings['proxy_user']}\n";
579
				$proxypas .= "{$settings['proxy_passwd']}\n";
580
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
581
			}
582
			$conf .= " \n";
583
		}
584 8dc3ef67 Scott Ullrich
	}
585
586 17c98ba9 jim-p
	// Add a remote network route if set, and only for p2p modes.
587
	if ((substr($settings['mode'], 0, 3) == "p2p") && is_subnet($settings['remote_network'])) {
588 8dc3ef67 Scott Ullrich
		list($ip, $mask) = explode('/', $settings['remote_network']);
589
		$mask = gen_subnet_mask($mask);
590 d799787e Matthew Grooms
		$conf .= "route $ip $mask\n";
591 8dc3ef67 Scott Ullrich
	}
592 afb07cf1 Scott Ullrich
593 d799787e Matthew Grooms
	// Write the settings for the keys
594 3c11bd3c Matthew Grooms
	switch($settings['mode']) {
595
		case 'p2p_shared_key':
596
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
597
			break;
598
		case 'p2p_tls':
599
		case 'server_tls':
600
		case 'server_tls_user':
601 e62e2f8b Ermal Lu?i
		case 'server_user':
602 3c11bd3c Matthew Grooms
			$ca = lookup_ca($settings['caref']);
603
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
604
			$cert = lookup_cert($settings['certref']);
605
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
606
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
607
			if ($mode == 'server')
608 fe787fc7 Matthew Grooms
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
609 6db02381 jim-p
			if (!empty($settings['crlref'])) {
610
				$crl = lookup_crl($settings['crlref']);
611 cfcc6994 jim-p
				crl_update($crl);
612 6db02381 jim-p
				openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify");
613
			}
614 db746ce2 Ermal Lu?i
			if ($settings['tls']) {
615 756720e2 Pierre POMES
				if ($mode == "server") 
616 db746ce2 Ermal Lu?i
					$tlsopt = 0;
617
				else
618
					$tlsopt = 1;
619
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
620
			}
621 3c11bd3c Matthew Grooms
			break;
622 8dc3ef67 Scott Ullrich
	}
623
624 1cb0b40a Matthew Grooms
	if ($settings['compression'])
625 d799787e Matthew Grooms
		$conf .= "comp-lzo\n";
626
627
	if ($settings['passtos'])
628
		$conf .= "passtos\n";
629
630
	if ($settings['resolve_retry'])
631
		$conf .= "resolv-retry infinite\n";
632
633
	if ($settings['dynamic_ip']) {
634
		$conf .= "persist-remote-ip\n";
635
		$conf .= "float\n";
636 8dc3ef67 Scott Ullrich
	}
637 afb07cf1 Scott Ullrich
638 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
639
640
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
641
	file_put_contents($fpath, $conf);
642 f9ac3784 Ermal Lu?i
	//chown($fpath, 'nobody');
643
	//chgrp($fpath, 'nobody');
644 6f27412f Ermal Lu?i
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
645
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
646
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
647
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
648 d799787e Matthew Grooms
}
649
650 fc05822b jim-p
function openvpn_restart($mode, $settings) {
651 d799787e Matthew Grooms
	global $g, $config;
652
653
	$vpnid = $settings['vpnid'];
654
	$mode_id = $mode.$vpnid;
655
656 76369bfc Matthew Grooms
	/* kill the process if running */
657 705c8ec9 Matthew Grooms
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
658 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
659 705c8ec9 Matthew Grooms
660 76369bfc Matthew Grooms
		/* read the pid file */
661
		$pid = rtrim(file_get_contents($pfile));
662
		unlink($pfile);
663 705c8ec9 Matthew Grooms
664 76369bfc Matthew Grooms
		/* send a term signal to the process */
665
		posix_kill($pid, SIGTERM);
666
667
		/* wait until the process exits */
668
		while(posix_kill($pid, 0))
669
			usleep(250000);
670
	}
671 d799787e Matthew Grooms
672 a1cab2c7 Ermal
	if (isset($settings['disable']))
673 d799787e Matthew Grooms
		return;
674
675 705c8ec9 Matthew Grooms
	/* start the new process */
676 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
677 5a7cc1f9 Ermal
	mwexec_bg("/usr/local/sbin/openvpn --config {$fpath}");
678 847cd48d Ermal
679
	if (!$g['booting'])
680
		send_event("filter reload");
681 afb07cf1 Scott Ullrich
}
682
683 dc408939 Matthew Grooms
function openvpn_delete($mode, & $settings) {
684 d799787e Matthew Grooms
	global $g, $config;
685
686
	$vpnid = $settings['vpnid'];
687
	$mode_id = $mode.$vpnid;
688
689 095a95ae Matthew Grooms
	$tunname = "tun{$vpnid}";
690
	if ($mode == "server")
691
		$devname = "ovpns{$vpnid}";
692
	else
693
		$devname = "ovpnc{$vpnid}";
694 dc408939 Matthew Grooms
695 76369bfc Matthew Grooms
	/* kill the process if running */
696 dc408939 Matthew Grooms
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
697 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
698 dc408939 Matthew Grooms
699 76369bfc Matthew Grooms
		/* read the pid file */
700
		$pid = trim(file_get_contents($pfile));
701
		unlink($pfile);
702
703
		/* send a term signal to the process */
704
		posix_kill($pid, SIGTERM);
705
	}
706 705c8ec9 Matthew Grooms
707 095a95ae Matthew Grooms
	/* remove the device from the openvpn group */
708
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
709
710 dc408939 Matthew Grooms
	/* restore the original adapter name */
711
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
712
713
	/* remove the configuration files */
714
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
715 d799787e Matthew Grooms
}
716 afb07cf1 Scott Ullrich
717 dc408939 Matthew Grooms
function openvpn_resync_csc(& $settings) {
718 8dc3ef67 Scott Ullrich
	global $g, $config;
719
720 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
721 8dc3ef67 Scott Ullrich
722 a1cab2c7 Ermal
	if (isset($settings['disable'])) {
723 d799787e Matthew Grooms
		unlink_if_exists($fpath);
724 c876662c Scott Ullrich
		return;
725
	}
726 d799787e Matthew Grooms
727 8dc3ef67 Scott Ullrich
	$conf = '';
728 d799787e Matthew Grooms
	if ($settings['block'])
729
		$conf .= "disable\n";
730
731
	if ($settings['push_reset'])
732
		$conf .= "push-reset\n";
733
734
	if (!empty($settings['tunnel_network'])) {
735
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
736 96033063 Erik Fonnesbeck
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
737 298fe5ae jim-p
		$serverip = long2ip32($baselong + 1);
738
		$clientip = long2ip32($baselong + 2);
739
		/* Because this is being pushed, the order from the client's point of view. */
740 002cacab jim-p
		if ($settings['dev_mode'] == 'tun')
741
			$conf .= "ifconfig-push {$clientip} {$serverip}\n";
742
		else
743
			$conf .= "ifconfig-push {$clientip} {$mask}\n";
744 8dc3ef67 Scott Ullrich
	}
745 6d031071 Martin Fuchs
746 d799787e Matthew Grooms
	openvpn_add_dhcpopts($settings, $conf);
747 8dc3ef67 Scott Ullrich
748 d799787e Matthew Grooms
	if ($settings['gwredir'])
749
		$conf .= "push \"redirect-gateway def1\"\n";
750 6d031071 Martin Fuchs
751 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
752 8dc3ef67 Scott Ullrich
753 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
754
	chown($fpath, 'nobody');
755
	chgrp($fpath, 'nobody');
756
}
757 8dc3ef67 Scott Ullrich
758 dc408939 Matthew Grooms
function openvpn_delete_csc(& $settings) {
759 add2e3f7 Scott Ullrich
	global $g, $config;
760 3c2e5528 Scott Ullrich
761 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
762 d799787e Matthew Grooms
	unlink_if_exists($fpath);
763 267ab13f Ermal Luçi
}
764 afb07cf1 Scott Ullrich
765 24012690 Scott Ullrich
// Resync the configuration and restart the VPN
766 fc05822b jim-p
function openvpn_resync($mode, $settings) {
767 dc408939 Matthew Grooms
	openvpn_reconfigure($mode, $settings);
768
	openvpn_restart($mode, $settings);
769 afb07cf1 Scott Ullrich
}
770
771 add2e3f7 Scott Ullrich
// Resync and restart all VPNs
772 c7f60193 Ermal
function openvpn_resync_all($interface = "") {
773 d799787e Matthew Grooms
	global $g, $config;
774 267ab13f Ermal Luçi
775 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
776
		return;
777 3cb54b54 Matthew Grooms
	// delay our setup until the system
778
	// has a chance to init our paths
779
	if (!file_exists($g['varetc_path']."/openvpn") ||
780
		!file_exists($g['varetc_path']."/openvpn-csc"))
781
		return;
782
783 34bc1324 Matthew Grooms
	if (!is_array($config['openvpn']))
784
		$config['openvpn'] = array();
785
786 15b414e6 Matthew Grooms
/*
787 34bc1324 Matthew Grooms
	if (!$config['openvpn']['dh-parameters']) {
788
		echo "Configuring OpenVPN Parameters ...\n";
789 035e4289 Matthew Grooms
		$dh_parameters = openvpn_create_dhparams(1024);
790 34bc1324 Matthew Grooms
		$dh_parameters = base64_encode($dh_parameters);
791
		$config['openvpn']['dh-parameters'] = $dh_parameters;
792 c67dd94e Bill Marquette
		write_config("OpenVPN DH parameters");
793 34bc1324 Matthew Grooms
	}
794
795
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
796
	if (!file_exists($path_ovdh)) {
797
		$dh_parameters = $config['openvpn']['dh-parameters'];
798
		$dh_parameters = base64_decode($dh_parameters);
799
		file_put_contents($path_ovdh, $dh_parameters);
800
	}
801 15b414e6 Matthew Grooms
*/
802 739c9efd Ermal
	if ($interface <> "")
803 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances for interface " . convert_friendly_interface_to_friendly_descr($interface) . ".");
804 739c9efd Ermal
	else
805 a82e6d37 Chris Buechler
		log_error("Resyncing OpenVPN instances."); 
806 34bc1324 Matthew Grooms
807 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-server'])) {
808
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
809 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
810 c7f60193 Ermal
				continue;
811 dc408939 Matthew Grooms
			openvpn_resync('server', $settings);
812 c7f60193 Ermal
		}
813
	}
814 5b237745 Scott Ullrich
815 c7f60193 Ermal
	if (is_array($config['openvpn']['openvpn-client'])) {
816
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
817 739c9efd Ermal
			if ($interface <> "" && $interface != $settings['interface'])
818 c7f60193 Ermal
				continue;
819 dc408939 Matthew Grooms
			openvpn_resync('client', $settings);
820 c7f60193 Ermal
		}
821
	}
822 afb07cf1 Scott Ullrich
823 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-csc']))
824 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
825
			openvpn_resync_csc($settings);
826 afb07cf1 Scott Ullrich
827 5b237745 Scott Ullrich
}
828 702a4702 Scott Ullrich
829 453d9c96 jim-p
function openvpn_get_active_servers($type="multipoint") {
830 71ca2cb2 Ermal
	global $config, $g;
831
832 53663f57 jim-p
	$servers = array();
833
	if (is_array($config['openvpn']['openvpn-server'])) {
834
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
835 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
836
				continue;
837
838 53663f57 jim-p
			$prot = $settings['protocol'];
839
			$port = $settings['local_port'];
840
	
841
			$server = array();
842 95305736 jim-p
			$server['port'] = ($settings['local_port']) ? $settings['local_port'] : 1194;
843 41be629f jim-p
			$server['mode'] = $settings['mode'];
844 53663f57 jim-p
			if ($settings['description'])
845
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
846
			else
847
				$server['name'] = "Server {$prot}:{$port}";
848
			$server['conns'] = array();
849
	
850 71ca2cb2 Ermal
			$vpnid = $settings['vpnid'];
851 95305736 jim-p
			$mode_id = "server{$vpnid}";
852 71ca2cb2 Ermal
			$server['mgmt'] = $mode_id;
853 95305736 jim-p
			$socket = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
854 453d9c96 jim-p
			list($tn, $sm) = explode('/', $settings['tunnel_network']);
855
856
			if ((($server['mode'] == "p2p_shared_key") || ($sm >= 30) ) && ($type == "p2p"))
857 95305736 jim-p
				$servers[] = openvpn_get_client_status($server, $socket);
858 453d9c96 jim-p
			elseif (($server['mode'] != "p2p_shared_key") && ($type == "multipoint") && ($sm < 30))
859 95305736 jim-p
				$servers[] = openvpn_get_server_status($server, $socket);
860 453d9c96 jim-p
861 95305736 jim-p
		}
862
	}
863
	return $servers;
864
}
865 b0140675 Ermal
866 95305736 jim-p
function openvpn_get_server_status($server, $socket) {
867
	$errval;
868
	$errstr;
869
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
870
	if ($fp) {
871
		stream_set_timeout($fp, 1);
872
873
		/* send our status request */
874
		fputs($fp, "status 2\n");
875
876
		/* recv all response lines */
877
		while (!feof($fp)) {
878
879
			/* read the next line */
880
			$line = fgets($fp, 1024);
881
882
			$info = stream_get_meta_data($fp);
883
			if ($info['timed_out'])
884
				break;
885
886
			/* parse header list line */
887
			if (strstr($line, "HEADER"))
888
				continue;
889
890
			/* parse end of output line */
891
			if (strstr($line, "END") || strstr($line, "ERROR"))
892
				break;
893
894
			/* parse client list line */
895
			if (strstr($line, "CLIENT_LIST")) {
896
				$list = explode(",", $line);
897 53663f57 jim-p
				$conn = array();
898 95305736 jim-p
				$conn['common_name'] = $list[1];
899
				$conn['remote_host'] = $list[2];
900
				$conn['virtual_addr'] = $list[3];
901
				$conn['bytes_recv'] = $list[4];
902
				$conn['bytes_sent'] = $list[5];
903
				$conn['connect_time'] = $list[6];
904 53663f57 jim-p
				$server['conns'][] = $conn;
905
			}
906
		}
907 95305736 jim-p
908
		/* cleanup */
909
		fclose($fp);
910
	} else {
911
		$conn = array();
912
		$conn['common_name'] = "[error]";
913
		$conn['remote_host'] = "Management Daemon Unreachable";
914
		$conn['virtual_addr'] = "";
915
		$conn['bytes_recv'] = 0;
916
		$conn['bytes_sent'] = 0;
917
		$conn['connect_time'] = 0;
918
		$server['conns'][] = $conn;
919 53663f57 jim-p
	}
920 95305736 jim-p
	return $server;
921 53663f57 jim-p
}
922
923
function openvpn_get_active_clients() {
924 71ca2cb2 Ermal
	global $config, $g;
925
926 53663f57 jim-p
	$clients = array();
927
	if (is_array($config['openvpn']['openvpn-client'])) {
928
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
929
	
930 6b2dcac5 Ermal
			if (empty($settings) || isset($settings['disable']))
931
				continue;
932
933 53663f57 jim-p
			$prot = $settings['protocol'];
934 95305736 jim-p
			$port = ($settings['local_port']) ? ":{$settings['local_port']}" : "";
935 53663f57 jim-p
	
936
			$client = array();
937
			$client['port'] = $settings['local_port'];
938
			if ($settings['description'])
939 95305736 jim-p
				$client['name'] = "{$settings['description']} {$prot}{$port}";
940 53663f57 jim-p
			else
941 95305736 jim-p
				$client['name'] = "Client {$prot}{$port}";
942 53663f57 jim-p
	
943 71ca2cb2 Ermal
			$vpnid = $settings['vpnid'];
944 95305736 jim-p
			$mode_id = "client{$vpnid}";
945 71ca2cb2 Ermal
			$client['mgmt'] = $mode_id;
946 95305736 jim-p
			$socket = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
947 53663f57 jim-p
			$client['status']="down";
948 95305736 jim-p
949
			$clients[] = openvpn_get_client_status($client, $socket);
950
		}
951
	}
952
	return $clients;
953
}
954
955
function openvpn_get_client_status($client, $socket) {
956
	$errval;
957
	$errstr;
958
	$fp = @stream_socket_client($socket, $errval, $errstr, 1);
959
	if ($fp) {
960
		stream_set_timeout($fp, 1);
961
		/* send our status request */
962
		fputs($fp, "state 1\n");
963
964
		/* recv all response lines */
965
		while (!feof($fp)) {
966
			/* read the next line */
967
			$line = fgets($fp, 1024);
968
969
			$info = stream_get_meta_data($fp);
970
			if ($info['timed_out'])
971
				break;
972
973
			/* Get the client state */
974
			if (strstr($line,"CONNECTED")) {
975
				$client['status']="up";
976
				$list = explode(",", $line);
977
978
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
979
				$client['virtual_addr']  = $list[3];
980
				$client['remote_host'] = $list[4];
981
			}
982 453d9c96 jim-p
			if (strstr($line,"CONNECTING")) {
983
				$client['status']="connecting";
984
			}
985
			if (strstr($line,"ASSIGN_IP")) {
986
				$client['status']="waiting";
987
				$list = explode(",", $line);
988
989
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
990
				$client['virtual_addr']  = $list[3];
991
			}
992
			if (strstr($line,"RECONNECTING")) {
993
				$client['status']="reconnecting";
994
				$list = explode(",", $line);
995
996
				$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
997
				$client['status'] .= "; " . $list[2];
998
			}
999 95305736 jim-p
			/* parse end of output line */
1000
			if (strstr($line, "END") || strstr($line, "ERROR"))
1001
				break;
1002
		}
1003
1004
		/* If up, get read/write stats */
1005
		if (strcmp($client['status'], "up") == 0) {
1006
			fputs($fp, "status 2\n");
1007
			/* recv all response lines */
1008
			while (!feof($fp)) {
1009
				/* read the next line */
1010
				$line = fgets($fp, 1024);
1011
1012
				$info = stream_get_meta_data($fp);
1013
				if ($info['timed_out'])
1014
					break;
1015
1016
				if (strstr($line,"TCP/UDP read bytes")) {
1017
					$list = explode(",", $line);
1018
					$client['bytes_recv'] = $list[1];
1019 53663f57 jim-p
				}
1020 95305736 jim-p
1021
				if (strstr($line,"TCP/UDP write bytes")) {
1022
					$list = explode(",", $line);
1023
					$client['bytes_sent'] = $list[1];
1024 53663f57 jim-p
				}
1025 95305736 jim-p
1026
				/* parse end of output line */
1027
				if (strstr($line, "END"))
1028
					break;
1029 53663f57 jim-p
			}
1030
		}
1031 95305736 jim-p
1032
		fclose($fp);
1033
1034
	} else {
1035
		$DisplayNote=true;
1036
		$client['remote_host'] = "No Management Daemon";
1037
		$client['virtual_addr'] = "See Note Below";
1038
		$client['bytes_recv'] = 0;
1039
		$client['bytes_sent'] = 0;
1040
		$client['connect_time'] = 0;
1041 53663f57 jim-p
	}
1042 95305736 jim-p
	return $client;
1043 53663f57 jim-p
}
1044 8e022a76 jim-p
1045
function openvpn_refresh_crls() {
1046
	global $g, $config;
1047
1048
	if (!file_exists($g['varetc_path']."/openvpn"))
1049
		return;
1050
1051
	if (is_array($config['openvpn']['openvpn-server'])) {
1052
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
1053
			if (empty($settings))
1054
				continue;
1055
			if (isset($settings['disable']))
1056
				continue;
1057
			// Write the settings for the keys
1058
			switch($settings['mode']) {
1059
				case 'p2p_tls':
1060
				case 'server_tls':
1061
				case 'server_tls_user':
1062
				case 'server_user':
1063
					if (!empty($settings['crlref'])) {
1064
						$crl = lookup_crl($settings['crlref']);
1065 728003c8 jim-p
						crl_update($crl);
1066 8e022a76 jim-p
						$fpath = $g['varetc_path']."/openvpn/server{$settings['vpnid']}.crl-verify";
1067
						file_put_contents($fpath, base64_decode($crl['text']));
1068
						@chmod($fpath, 0644);
1069
					}
1070
					break;
1071
			}
1072
		}
1073
	}
1074
}
1075
1076 756720e2 Pierre POMES
?>