Project

General

Profile

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