Project

General

Profile

Download (17.6 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 8dc3ef67 Scott Ullrich
53 8411b218 Matthew Grooms
$openvpn_prots = array("UDP", "TCP");
54 702a4702 Scott Ullrich
55 3c11bd3c Matthew Grooms
/* 
56
 * The User Auth mode below is disabled because
57
 * OpenVPN erroneously requires that we provide
58
 * a CA configuration parameter. In this mode,
59
 * clients don't send a certificate so there is
60
 * no need for a CA. If we require that admins
61
 * provide one in the pfSense UI due to a bogus
62
 * requirement imposed by OpenVPN, it could be
63
 * considered very confusing ( I know I was ).
64
 *
65
 * -mgrooms
66
 */
67
68 fe787fc7 Matthew Grooms
$openvpn_dh_lengths = array(
69
	1024, 2048, 4096 );
70
71 3c11bd3c Matthew Grooms
$openvpn_server_modes = array(
72
	'p2p_tls' => "Peer to Peer ( SSL/TLS )",
73
	'p2p_shared_key' => "Peer to Peer ( Shared Key )",
74
	'server_tls' => "Remote Access ( SSL/TLS )",
75
//	'server_user' => "Remote Access ( User Auth )",
76
	'server_tls_user' => "Remote Access ( SSL/TLS + User Auth )");
77
78
$openvpn_client_modes = array(
79
	'p2p_tls' => "Peer to Peer ( SSL/TLS )",
80
	'p2p_shared_key' => "Peer to Peer ( Shared Key )" );
81
82
function openvpn_create_key() {
83
84
	$fp = popen("/usr/local/sbin/openvpn --genkey --secret /dev/stdout 2>/dev/null", "r");
85
	if (!$fp)
86
		return false;
87
88
	$rslt = stream_get_contents($fp);
89
	pclose($fp);
90
91
	return $rslt;
92
}
93 d799787e Matthew Grooms
94 8411b218 Matthew Grooms
function openvpn_create_dhparams($bits) {
95 34bc1324 Matthew Grooms
96 3c11bd3c Matthew Grooms
	$fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r");
97 34bc1324 Matthew Grooms
	if (!$fp)
98
		return false;
99
100
	$rslt = stream_get_contents($fp);
101
	pclose($fp);
102
103
	return $rslt;
104
}
105
106 d799787e Matthew Grooms
function openvpn_vpnid_used($vpnid) {
107 8be2d6d3 Ermal Luçi
	global $config;
108
109 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-server']))
110 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
111 f432e364 Matthew Grooms
			if ($vpnid == $settings['vpnid'])
112 d799787e Matthew Grooms
				return true;
113
114
	if (is_array($config['openvpn']['openvpn-client']))
115 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
116 f432e364 Matthew Grooms
			if ($vpnid == $settings['vpnid'])
117 d799787e Matthew Grooms
				return true;
118 04a6e900 Ermal Luçi
119 d799787e Matthew Grooms
	return false;
120
}
121
122
function openvpn_vpnid_next() {
123
124
	$vpnid = 1;
125
	while(openvpn_vpnid_used($vpnid))
126
		$vpnid++;
127
128
	return $vpnid;
129
}
130
131 f432e364 Matthew Grooms
function openvpn_port_used($prot, $port) {
132
	global $config;
133
134
	if (is_array($config['openvpn']['openvpn-server']))
135 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
136 f432e364 Matthew Grooms
			if ($port == $settings['local_port'] &&
137
				$prot == $settings['protocol'])
138
				return $settings['vpnid'];
139
140
	if (is_array($config['openvpn']['openvpn-client']))
141 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
142 f432e364 Matthew Grooms
			if ($port == $settings['local_port'] &&
143
				$prot == $settings['protocol'])
144
				return $settings['vpnid'];
145
146
	return 0;
147
}
148
149
function openvpn_port_next($prot) {
150
151
	$port = 1194;
152
	while(openvpn_port_used($prot, $port))
153
		$port++;
154
155
	return $port;
156
}
157
158 d799787e Matthew Grooms
function openvpn_get_cipherlist() {
159
160
	$ciphers = array();
161
	$cipher_out = shell_exec('openvpn --show-ciphers | grep "default key" | awk \'{print $1, "(" $2 "-" $3 ")";}\'');
162
	$cipher_lines = explode("\n", trim($cipher_out));
163
	sort($cipher_lines);
164
	foreach ($cipher_lines as $line) {
165
		$words = explode(' ', $line);
166
		$ciphers[$words[0]] = "{$words[0]} {$words[1]}";
167 8be2d6d3 Ermal Luçi
	}
168 d799787e Matthew Grooms
169
	return $ciphers;
170
}
171
172
function openvpn_validate_host($value, $name) {
173
	$value = trim($value);
174 3e2bd5de Ermal Lu?i
	if (empty($value) || (!is_domain($value) && !is_ipaddr($value)))
175 d799787e Matthew Grooms
		return "The field '$name' must contain a valid IP address or domain name.";
176
	return false;
177 8dc3ef67 Scott Ullrich
}
178
179
function openvpn_validate_port($value, $name) {
180
	$value = trim($value);
181 3e2bd5de Ermal Lu?i
	if (empty($value) || !is_numeric($value) || $value < 0 || ($value > 65535))
182 8dc3ef67 Scott Ullrich
		return "The field '$name' must contain a valid port, ranging from 0 to 65535.";
183 b398bbca Martin Fuchs
	return false;
184 8dc3ef67 Scott Ullrich
}
185
186
function openvpn_validate_cidr($value, $name) {
187
	$value = trim($value);
188
	if (!empty($value)) {
189
		list($ip, $mask) = explode('/', $value);
190
		if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
191
			return "The field '$name' must contain a valid CIDR range.";
192
	}
193
	return false;
194 afb07cf1 Scott Ullrich
}
195
196 d799787e Matthew Grooms
function openvpn_add_dhcpopts(& $settings, & $conf) {
197 afb07cf1 Scott Ullrich
198 d799787e Matthew Grooms
	if (!empty($settings['dns_domain'])) 
199
		$conf .= "push \"dhcp-option DOMAIN {$settings['dns_domain']}\"\n";
200 add2e3f7 Scott Ullrich
201 d799787e Matthew Grooms
	if (!empty($settings['dns_server1']))
202
		$conf .= "push \"dhcp-option DNS {$settings['dns_server1']}\"\n";
203
	if (!empty($settings['dns_server2']))
204
		$conf .= "push \"dhcp-option DNS {$settings['dns_server2']}\"\n";
205
	if (!empty($settings['dns_server3']))
206
		$conf .= "push \"dhcp-option DNS {$settings['dns_server3']}\"\n";
207
	if (!empty($settings['dns_server4']))
208
		$conf .= "push \"dhcp-option DNS {$settings['dns_server4']}\"\n";
209 f9927473 Scott Ullrich
210 d799787e Matthew Grooms
	if (!empty($settings['ntp_server1']))
211
		$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
212
	if (!empty($settings['ntp_server2']))
213
		$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
214 f9927473 Scott Ullrich
215 d799787e Matthew Grooms
	if ($settings['netbios_enable']) {
216 add2e3f7 Scott Ullrich
217 095a95ae Matthew Grooms
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0))
218
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
219
		if (!empty($settings['dhcp_nbtscope'])) 
220 d799787e Matthew Grooms
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
221 8dc3ef67 Scott Ullrich
222 d799787e Matthew Grooms
		if (!empty($settings['wins_server1']))
223
			$conf .= "push \"dhcp-option WINS {$settings['wins_server1']}\"\n";
224
		if (!empty($settings['wins_server2']))
225
			$conf .= "push \"dhcp-option WINS {$settings['wins_server2']}\"\n";
226 add2e3f7 Scott Ullrich
227 d799787e Matthew Grooms
		if (!empty($settings['nbdd_server1']))
228
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server1']}\"\n";
229
	}
230 8dc3ef67 Scott Ullrich
231 d799787e Matthew Grooms
	if ($settings['gwredir']) 
232
		$conf .= "push \"redirect-gateway def1\"\n";
233
}
234 24012690 Scott Ullrich
235 d799787e Matthew Grooms
function openvpn_add_custom(& $settings, & $conf) {
236 add2e3f7 Scott Ullrich
237 d799787e Matthew Grooms
	if ($settings['custom_options']) {
238 8dc3ef67 Scott Ullrich
239 d799787e Matthew Grooms
		$options = explode(';', $settings['custom_options']);
240
241
		if (is_array($options)) {
242
			foreach ($options as $option)
243
				$conf .= "$option\n";
244
		} else
245
			$conf .= "{$settings['custom_options']}\n";
246 add2e3f7 Scott Ullrich
	}
247
}
248
249 d799787e Matthew Grooms
function openvpn_add_keyfile(& $data, & $conf, $mode_id, $directive) {
250
	global $g;
251 add2e3f7 Scott Ullrich
252 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.{$directive}";
253
	file_put_contents($fpath, base64_decode($data));
254
	chown($fpath, 'nobody');
255
	chgrp($fpath, 'nobody');
256
257
	$conf .= "{$directive} {$fpath}\n";
258 4eefa6e8 Scott Ullrich
}
259
260 dc408939 Matthew Grooms
function openvpn_reconfigure($mode,& $settings) {
261 add2e3f7 Scott Ullrich
	global $g, $config;
262 afb07cf1 Scott Ullrich
263 93a0a028 Ermal Luçi
	if (empty($settings))
264
		return;
265 4eefa6e8 Scott Ullrich
	if ($settings['disable']) 
266
		return;
267
268 fdd725f0 Ermal Luçi
	/*
269 d799787e Matthew Grooms
	 * NOTE: Deleting tap devices causes spontaneous reboots. Instead,
270
	 * we use a vpnid number which is allocated for a particular client
271
	 * or server configuration. ( see openvpn_vpnid_next() )
272 fdd725f0 Ermal Luçi
	 */
273 8874c692 Ermal Luçi
274 d799787e Matthew Grooms
	$vpnid = $settings['vpnid'];
275
	$mode_id = $mode.$vpnid;
276 8874c692 Ermal Luçi
277 dc408939 Matthew Grooms
	$tunname = "tun{$vpnid}";
278 d799787e Matthew Grooms
	if ($mode == "server")
279
		$devname = "ovpns{$vpnid}";
280
	else
281
		$devname = "ovpnc{$vpnid}";
282 8874c692 Ermal Luçi
283 dc408939 Matthew Grooms
	/* is our device already configured */
284
	if (mwexec("/sbin/ifconfig {$devname}")) {
285
286
		/* create the tap device if required */
287
		if (!file_exists("/dev/{$tunname}"))
288
			exec("/sbin/ifconfig {$tunname} create");
289 98872d89 Ermal Luçi
290 dc408939 Matthew Grooms
		/* rename the device */
291
		mwexec("/sbin/ifconfig {$tunname} name {$devname}");
292 095a95ae Matthew Grooms
293
		/* add the device to the openvpn group */
294
		mwexec("/sbin/ifconfig {$devname} group openvpn");
295 dc408939 Matthew Grooms
	}
296 d799787e Matthew Grooms
297 dc408939 Matthew Grooms
	$pfile = $g['varrun_path'] . "/openvpn_{$mode_id}.pid";
298 c0cf27aa Scott Ullrich
	$proto = ($settings['protocol'] == 'UDP' ? 'udp' : "tcp-{$mode}");
299
	$cipher = $settings['crypto'];
300 d799787e Matthew Grooms
301
	$interface = $settings['interface'];
302 67b0902f pierrepomes
	$ipaddr = $settings['ipaddr'];
303 d799787e Matthew Grooms
304 67b0902f pierrepomes
	// If a specific ip address (VIP) is requested, use it.
305
	// Otherwise, if a specific interface is requested, use it
306
	// If "any" interface was selected, local directive will be ommited.
307
	if (!empty($ipaddr)) {
308
		$iface_ip=$ipaddr;
309 3d06e8f0 pierrepomes
	} else {
310 67b0902f pierrepomes
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
311 507af8dd pierrepomes
			$iface_ip=get_interface_ip($interface);
312 67b0902f pierrepomes
		}
313 3d06e8f0 pierrepomes
	}
314 d799787e Matthew Grooms
315 3c11bd3c Matthew Grooms
	$conf  = "dev {$devname}\n";
316
	$conf .= "dev-type tun\n";
317
	$conf .= "dev-node /dev/{$tunname}\n";
318
	$conf .= "writepid {$pfile}\n";
319
	$conf .= "#user nobody\n";
320
	$conf .= "#group nobody\n";
321 d1014c18 Chris Buechler
	$conf .= "script-security 3\n";
322 3c11bd3c Matthew Grooms
	$conf .= "daemon\n";
323
	$conf .= "keepalive 10 60\n";
324
	$conf .= "ping-timer-rem\n";
325
	$conf .= "persist-tun\n";
326
	$conf .= "persist-key\n";
327
	$conf .= "proto {$proto}\n";
328
	$conf .= "cipher {$cipher}\n";
329
	$conf .= "up /etc/rc.filter_configure\n";
330
	$conf .= "down /etc/rc.filter_configure\n";
331
332 67b0902f pierrepomes
	if (!empty($iface_ip)) {
333
		$conf .= "local {$iface_ip}\n";	
334
	}
335 d799787e Matthew Grooms
336 67b0902f pierrepomes
	// server specific settings
337 8dc3ef67 Scott Ullrich
	if ($mode == 'server') {
338 d799787e Matthew Grooms
339
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
340 8dc3ef67 Scott Ullrich
		$mask = gen_subnet_mask($mask);
341
342 3c11bd3c Matthew Grooms
		// configure tls modes
343
		switch($settings['mode']) {
344
			case 'p2p_tls':
345
			case 'server_tls':
346
			case 'server_tls_user':
347 d799787e Matthew Grooms
				$conf .= "tls-server\n";
348 3c11bd3c Matthew Grooms
				break;
349 8dc3ef67 Scott Ullrich
		}
350 d799787e Matthew Grooms
351 3c11bd3c Matthew Grooms
		// configure p2p/server modes
352
		switch($settings['mode']) {
353
			case 'p2p_tls':
354
			case 'p2p_shared_key':
355
				$baselong = ip2long($ip) & ip2long($mask);
356
				$ip1 = long2ip($baselong + 1);
357
				$ip2 = long2ip($baselong + 2);
358
				$conf .= "ifconfig $ip1 $ip2\n";
359
				break;
360
			case 'server_tls':
361
			case 'server_user':
362
			case 'server_tls_user':
363
				$conf .= "server {$ip} {$mask}\n";
364
				$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
365
				break;
366 8dc3ef67 Scott Ullrich
		}
367
368 3c11bd3c Matthew Grooms
		// configure user auth modes
369
		switch($settings['mode']) {
370
			case 'server_user':
371
				$conf .= "client-cert-not-required\n";
372
			case 'server_tls_user':
373
				$conf .= "username-as-common-name\n";
374
				$conf .= "auth-user-pass-verify /etc/inc/openvpn.auth-user.php via-env\n";
375
				break;
376 8dc3ef67 Scott Ullrich
		}
377
378 63084885 Matthew Grooms
		// The local port to listen on
379 d799787e Matthew Grooms
		$conf .= "lport {$settings['local_port']}\n";
380 c0cf27aa Scott Ullrich
381 63084885 Matthew Grooms
		// The management port to listen on
382
		$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
383
384 3c11bd3c Matthew Grooms
		if ($settings['maxclients'])
385 d799787e Matthew Grooms
			$conf .= "max-clients {$settings['maxclients']}\n";
386
387 3c11bd3c Matthew Grooms
		// Can we push routes
388
		if ($settings['local_network']) {
389
			list($ip, $mask) = explode('/', $settings['local_network']);
390
			$mask = gen_subnet_mask($mask);
391
			$conf .= "push \"route $ip $mask\"\n";
392
		}
393
394
		// Configure client dhcp options
395
		switch($settings['mode']) {
396
			case 'server_tls':
397
			case 'server_user':
398
			case 'server_tls_user':
399
				openvpn_add_dhcpopts($settings, $conf);
400
				break;
401
		}
402 d799787e Matthew Grooms
	}
403
404 3c11bd3c Matthew Grooms
	// client specific settings
405 d799787e Matthew Grooms
406 3c11bd3c Matthew Grooms
	if ($mode == 'client') {
407 d799787e Matthew Grooms
408 3c11bd3c Matthew Grooms
		// configure p2p mode
409
		switch($settings['mode']) {
410
			case 'p2p_tls':
411
				$conf .= "tls-client\n";
412
			case 'shared_key':
413
				$conf .= "client\n";
414
				break;
415
		}
416 d799787e Matthew Grooms
417
		// The port we'll listen at
418
		if ($settings['local_port'])
419
			$conf .= "lport {$settings['local_port']}\n";
420
		else
421
			$conf .= "nobind\n";
422 8dc3ef67 Scott Ullrich
423 3c11bd3c Matthew Grooms
		// The remote server
424
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
425
426 d799787e Matthew Grooms
		if (!empty($settings['use_shaper']))
427
			$conf .= "shaper {$settings['use_shaper']}\n";
428 ee506044 Scott Ullrich
429 d799787e Matthew Grooms
		if (!empty($settings['tunnel_network'])) {
430
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
431 8dc3ef67 Scott Ullrich
			$mask = gen_subnet_mask($mask);
432
			$baselong = ip2long($ip) & ip2long($mask);
433
			$ip1 = long2ip($baselong + 1);
434
			$ip2 = long2ip($baselong + 2);
435 d799787e Matthew Grooms
			$conf .= "ifconfig $ip2 $ip1\n";
436 8dc3ef67 Scott Ullrich
		}
437 d799787e Matthew Grooms
438 3c11bd3c Matthew Grooms
		if ($settings['proxy_addr'])
439 d799787e Matthew Grooms
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}\n";
440 8dc3ef67 Scott Ullrich
	}
441
442 3c11bd3c Matthew Grooms
	// Add a remote network route if set
443
	if ($settings['remote_network']) {
444 8dc3ef67 Scott Ullrich
		list($ip, $mask) = explode('/', $settings['remote_network']);
445
		$mask = gen_subnet_mask($mask);
446 d799787e Matthew Grooms
		$conf .= "route $ip $mask\n";
447 8dc3ef67 Scott Ullrich
	}
448 afb07cf1 Scott Ullrich
449 d799787e Matthew Grooms
	// Write the settings for the keys
450 3c11bd3c Matthew Grooms
	switch($settings['mode']) {
451
		case 'p2p_shared_key':
452
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
453
			break;
454
		case 'p2p_tls':
455
		case 'server_tls':
456
		case 'server_tls_user':
457
			$ca = lookup_ca($settings['caref']);
458
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
459
		case 'server_user':
460
			$cert = lookup_cert($settings['certref']);
461
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
462
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
463
			if ($mode == 'server')
464 fe787fc7 Matthew Grooms
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
465 3c11bd3c Matthew Grooms
			if ($settings['crl'])
466
				openvpn_add_keyfile($settings['crl'], $conf, $mode_id, "crl-verify");
467
			if ($settings['tls'])
468
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth");
469
			break;
470 8dc3ef67 Scott Ullrich
	}
471
472 1cb0b40a Matthew Grooms
	if ($settings['compression'])
473 d799787e Matthew Grooms
		$conf .= "comp-lzo\n";
474
475
	if ($settings['passtos'])
476
		$conf .= "passtos\n";
477
478
	if ($settings['resolve_retry'])
479
		$conf .= "resolv-retry infinite\n";
480
481
	if ($settings['dynamic_ip']) {
482
		$conf .= "persist-remote-ip\n";
483
		$conf .= "float\n";
484 8dc3ef67 Scott Ullrich
	}
485 afb07cf1 Scott Ullrich
486 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
487
488
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
489
	file_put_contents($fpath, $conf);
490
	chown($fpath, 'nobody');
491
	chgrp($fpath, 'nobody');
492
}
493
494 dc408939 Matthew Grooms
function openvpn_restart($mode, & $settings) {
495 d799787e Matthew Grooms
	global $g, $config;
496
497
	$vpnid = $settings['vpnid'];
498
	$mode_id = $mode.$vpnid;
499
500 76369bfc Matthew Grooms
	/* kill the process if running */
501 705c8ec9 Matthew Grooms
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
502 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
503 705c8ec9 Matthew Grooms
504 76369bfc Matthew Grooms
		/* read the pid file */
505
		$pid = rtrim(file_get_contents($pfile));
506
		unlink($pfile);
507 705c8ec9 Matthew Grooms
508 76369bfc Matthew Grooms
		/* send a term signal to the process */
509
		posix_kill($pid, SIGTERM);
510
511
		/* wait until the process exits */
512
		while(posix_kill($pid, 0))
513
			usleep(250000);
514
	}
515 d799787e Matthew Grooms
516
	if ($settings['disable'])
517
		return;
518
519 705c8ec9 Matthew Grooms
	/* start the new process */
520 d799787e Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
521
	mwexec_bg("nohup openvpn --config {$fpath}");
522
	touch("{$g['tmp_path']}/filter_dirty");
523 afb07cf1 Scott Ullrich
}
524
525 dc408939 Matthew Grooms
function openvpn_delete($mode, & $settings) {
526 d799787e Matthew Grooms
	global $g, $config;
527
528
	$vpnid = $settings['vpnid'];
529
	$mode_id = $mode.$vpnid;
530
531 095a95ae Matthew Grooms
	$tunname = "tun{$vpnid}";
532
	if ($mode == "server")
533
		$devname = "ovpns{$vpnid}";
534
	else
535
		$devname = "ovpnc{$vpnid}";
536 dc408939 Matthew Grooms
537 76369bfc Matthew Grooms
	/* kill the process if running */
538 dc408939 Matthew Grooms
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
539 76369bfc Matthew Grooms
	if (file_exists($pfile)) {
540 dc408939 Matthew Grooms
541 76369bfc Matthew Grooms
		/* read the pid file */
542
		$pid = trim(file_get_contents($pfile));
543
		unlink($pfile);
544
545
		/* send a term signal to the process */
546
		posix_kill($pid, SIGTERM);
547
	}
548 705c8ec9 Matthew Grooms
549 095a95ae Matthew Grooms
	/* remove the device from the openvpn group */
550
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
551
552 dc408939 Matthew Grooms
	/* restore the original adapter name */
553
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
554
555
	/* remove the configuration files */
556
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
557 d799787e Matthew Grooms
}
558 afb07cf1 Scott Ullrich
559 dc408939 Matthew Grooms
function openvpn_resync_csc(& $settings) {
560 8dc3ef67 Scott Ullrich
	global $g, $config;
561
562 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
563 8dc3ef67 Scott Ullrich
564 d799787e Matthew Grooms
	if ($settings['disable']) {
565
		unlink_if_exists($fpath);
566 c876662c Scott Ullrich
		return;
567
	}
568 d799787e Matthew Grooms
569 8dc3ef67 Scott Ullrich
	$conf = '';
570 d799787e Matthew Grooms
	if ($settings['block'])
571
		$conf .= "disable\n";
572
573
	if ($settings['push_reset'])
574
		$conf .= "push-reset\n";
575
576
	if (!empty($settings['tunnel_network'])) {
577
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
578 8dc3ef67 Scott Ullrich
		$baselong = ip2long($ip) & gen_subnet_mask_long($mask);
579 d799787e Matthew Grooms
		$ip1 = long2ip($baselong + 1);
580
		$ip2 = long2ip($baselong + 2);
581
		$conf .= "ifconfig-push {$ip1} {$ip2}\n";
582 8dc3ef67 Scott Ullrich
	}
583 6d031071 Martin Fuchs
584 d799787e Matthew Grooms
	openvpn_add_dhcpopts($settings, $conf);
585 8dc3ef67 Scott Ullrich
586 d799787e Matthew Grooms
	if ($settings['gwredir'])
587
		$conf .= "push \"redirect-gateway def1\"\n";
588 6d031071 Martin Fuchs
589 d799787e Matthew Grooms
	openvpn_add_custom($settings, $conf);
590 8dc3ef67 Scott Ullrich
591 d799787e Matthew Grooms
	file_put_contents($fpath, $conf);
592
	chown($fpath, 'nobody');
593
	chgrp($fpath, 'nobody');
594
}
595 8dc3ef67 Scott Ullrich
596 dc408939 Matthew Grooms
function openvpn_delete_csc(& $settings) {
597 add2e3f7 Scott Ullrich
	global $g, $config;
598 3c2e5528 Scott Ullrich
599 ea28182c Matthew Grooms
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
600 d799787e Matthew Grooms
	unlink_if_exists($fpath);
601 267ab13f Ermal Luçi
}
602 afb07cf1 Scott Ullrich
603 24012690 Scott Ullrich
// Resync the configuration and restart the VPN
604 dc408939 Matthew Grooms
function openvpn_resync($mode, & $settings) {
605
	openvpn_reconfigure($mode, $settings);
606
	openvpn_restart($mode, $settings);
607 afb07cf1 Scott Ullrich
}
608
609 add2e3f7 Scott Ullrich
// Resync and restart all VPNs
610
function openvpn_resync_all() {
611 d799787e Matthew Grooms
	global $g, $config;
612 267ab13f Ermal Luçi
613 3cb54b54 Matthew Grooms
	// delay our setup until the system
614
	// has a chance to init our paths
615
	if (!file_exists($g['varetc_path']."/openvpn") ||
616
		!file_exists($g['varetc_path']."/openvpn-csc"))
617
		return;
618
619 34bc1324 Matthew Grooms
	if (!is_array($config['openvpn']))
620
		$config['openvpn'] = array();
621
622 15b414e6 Matthew Grooms
/*
623 34bc1324 Matthew Grooms
	if (!$config['openvpn']['dh-parameters']) {
624
		echo "Configuring OpenVPN Parameters ...\n";
625 035e4289 Matthew Grooms
		$dh_parameters = openvpn_create_dhparams(1024);
626 34bc1324 Matthew Grooms
		$dh_parameters = base64_encode($dh_parameters);
627
		$config['openvpn']['dh-parameters'] = $dh_parameters;
628 c67dd94e Bill Marquette
		write_config("OpenVPN DH parameters");
629 34bc1324 Matthew Grooms
	}
630
631
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
632
	if (!file_exists($path_ovdh)) {
633
		$dh_parameters = $config['openvpn']['dh-parameters'];
634
		$dh_parameters = base64_decode($dh_parameters);
635
		file_put_contents($path_ovdh, $dh_parameters);
636
	}
637 15b414e6 Matthew Grooms
*/
638 34bc1324 Matthew Grooms
639 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-server']))
640 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
641
			openvpn_resync('server', $settings);
642 5b237745 Scott Ullrich
643 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-client']))
644 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
645
			openvpn_resync('client', $settings);
646 afb07cf1 Scott Ullrich
647 d799787e Matthew Grooms
	if (is_array($config['openvpn']['openvpn-csc']))
648 dc408939 Matthew Grooms
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
649
			openvpn_resync_csc($settings);
650 afb07cf1 Scott Ullrich
651 5b237745 Scott Ullrich
}
652 702a4702 Scott Ullrich
653 8874c692 Ermal Luçi
?>