Project

General

Profile

Download (25.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/* $Id$ */
4
/*
5
	$RCSfile$
6
	
7
	Copyright (C) 2008 Scott Ullrich <sullrich@gmail.com>
8
	All rights reserved.
9
	
10
	Copyright (C) 2006  Fernando Lemos
11
	All rights reserved.
12

    
13
	This file was rewritten from scratch by Fernando Lemos but
14
	*MIGHT* contain code previously written by:
15

    
16
	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
	DISABLE_PHP_LINT_CHECKING
44
	
45
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/openvpn	/usr/bin/openssl	/sbin/ifconfig
46
	pfSense_MODULE:	openvpn
47

    
48
*/
49
require_once('config.inc');
50
require_once("certs.inc");
51
require_once('pfsense-utils.inc');
52
require_once("auth.inc");
53

    
54
$openvpn_prots = array("UDP", "TCP");
55

    
56
$openvpn_dev_mode = array("tun", "tap");
57

    
58
/* 
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
$openvpn_dh_lengths = array(
72
	1024, 2048, 4096 );
73

    
74
$openvpn_server_modes = array(
75
	'p2p_tls' => "Peer to Peer ( SSL/TLS )",
76
	'p2p_shared_key' => "Peer to Peer ( Shared Key )",
77
	'server_tls' => "Remote Access ( SSL/TLS )",
78
	'server_user' => "Remote Access ( User Auth )",
79
	'server_tls_user' => "Remote Access ( SSL/TLS + User Auth )");
80

    
81
$openvpn_client_modes = array(
82
	'p2p_tls' => "Peer to Peer ( SSL/TLS )",
83
	'p2p_shared_key' => "Peer to Peer ( Shared Key )" );
84

    
85
function openvpn_create_key() {
86

    
87
	$fp = popen("/usr/local/sbin/openvpn --genkey --secret /dev/stdout 2>/dev/null", "r");
88
	if (!$fp)
89
		return false;
90

    
91
	$rslt = stream_get_contents($fp);
92
	pclose($fp);
93

    
94
	return $rslt;
95
}
96

    
97
function openvpn_create_dhparams($bits) {
98

    
99
	$fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r");
100
	if (!$fp)
101
		return false;
102

    
103
	$rslt = stream_get_contents($fp);
104
	pclose($fp);
105

    
106
	return $rslt;
107
}
108

    
109
function openvpn_vpnid_used($vpnid) {
110
	global $config;
111

    
112
	if (is_array($config['openvpn']['openvpn-server']))
113
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
114
			if ($vpnid == $settings['vpnid'])
115
				return true;
116

    
117
	if (is_array($config['openvpn']['openvpn-client']))
118
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
119
			if ($vpnid == $settings['vpnid'])
120
				return true;
121

    
122
	return false;
123
}
124

    
125
function openvpn_vpnid_next() {
126

    
127
	$vpnid = 1;
128
	while(openvpn_vpnid_used($vpnid))
129
		$vpnid++;
130

    
131
	return $vpnid;
132
}
133

    
134
function openvpn_port_used($prot, $port) {
135
	global $config;
136

    
137
	if (is_array($config['openvpn']['openvpn-server']))
138
		foreach ($config['openvpn']['openvpn-server'] as & $settings)
139
			if ($port == $settings['local_port'] &&
140
				$prot == $settings['protocol'])
141
				return $settings['vpnid'];
142

    
143
	if (is_array($config['openvpn']['openvpn-client']))
144
		foreach ($config['openvpn']['openvpn-client'] as & $settings)
145
			if ($port == $settings['local_port'] &&
146
				$prot == $settings['protocol'])
147
				return $settings['vpnid'];
148

    
149
	return 0;
150
}
151

    
152
function openvpn_port_next($prot) {
153

    
154
	$port = 1194;
155
	while(openvpn_port_used($prot, $port))
156
		$port++;
157

    
158
	return $port;
159
}
160

    
161
function openvpn_get_cipherlist() {
162

    
163
	$ciphers = array();
164
	$cipher_out = shell_exec('openvpn --show-ciphers | grep "default key" | awk \'{print $1, "(" $2 "-" $3 ")";}\'');
165
	$cipher_lines = explode("\n", trim($cipher_out));
166
	sort($cipher_lines);
167
	foreach ($cipher_lines as $line) {
168
		$words = explode(' ', $line);
169
		$ciphers[$words[0]] = "{$words[0]} {$words[1]}";
170
	}
171
	$ciphers["none"] = "None (No Encryption)";
172
	return $ciphers;
173
}
174

    
175
function openvpn_validate_host($value, $name) {
176
	$value = trim($value);
177
	if (empty($value) || (!is_domain($value) && !is_ipaddr($value)))
178
		return "The field '$name' must contain a valid IP address or domain name.";
179
	return false;
180
}
181

    
182
function openvpn_validate_port($value, $name) {
183
	$value = trim($value);
184
	if (empty($value) || !is_numeric($value) || $value < 0 || ($value > 65535))
185
		return "The field '$name' must contain a valid port, ranging from 0 to 65535.";
186
	return false;
187
}
188

    
189
function openvpn_validate_cidr($value, $name) {
190
	$value = trim($value);
191
	if (!empty($value)) {
192
		list($ip, $mask) = explode('/', $value);
193
		if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
194
			return "The field '$name' must contain a valid CIDR range.";
195
	}
196
	return false;
197
}
198

    
199
function openvpn_add_dhcpopts(& $settings, & $conf) {
200

    
201
	if (!empty($settings['dns_domain'])) 
202
		$conf .= "push \"dhcp-option DOMAIN {$settings['dns_domain']}\"\n";
203

    
204
	if (!empty($settings['dns_server1']))
205
		$conf .= "push \"dhcp-option DNS {$settings['dns_server1']}\"\n";
206
	if (!empty($settings['dns_server2']))
207
		$conf .= "push \"dhcp-option DNS {$settings['dns_server2']}\"\n";
208
	if (!empty($settings['dns_server3']))
209
		$conf .= "push \"dhcp-option DNS {$settings['dns_server3']}\"\n";
210
	if (!empty($settings['dns_server4']))
211
		$conf .= "push \"dhcp-option DNS {$settings['dns_server4']}\"\n";
212

    
213
	if (!empty($settings['ntp_server1']))
214
		$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
215
	if (!empty($settings['ntp_server2']))
216
		$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
217

    
218
	if ($settings['netbios_enable']) {
219

    
220
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0))
221
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
222
		if (!empty($settings['dhcp_nbtscope'])) 
223
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
224

    
225
		if (!empty($settings['wins_server1']))
226
			$conf .= "push \"dhcp-option WINS {$settings['wins_server1']}\"\n";
227
		if (!empty($settings['wins_server2']))
228
			$conf .= "push \"dhcp-option WINS {$settings['wins_server2']}\"\n";
229

    
230
		if (!empty($settings['nbdd_server1']))
231
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server1']}\"\n";
232
	}
233

    
234
	if ($settings['gwredir']) 
235
		$conf .= "push \"redirect-gateway def1\"\n";
236
}
237

    
238
function openvpn_add_custom(& $settings, & $conf) {
239

    
240
	if ($settings['custom_options']) {
241

    
242
		$options = explode(';', $settings['custom_options']);
243

    
244
		if (is_array($options)) {
245
			foreach ($options as $option)
246
				$conf .= "$option\n";
247
		} else
248
			$conf .= "{$settings['custom_options']}\n";
249
	}
250
}
251

    
252
function openvpn_add_keyfile(& $data, & $conf, $mode_id, $directive, $opt = "") {
253
	global $g;
254

    
255
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.{$directive}";
256
	file_put_contents($fpath, base64_decode($data));
257
	//chown($fpath, 'nobody');
258
	//chgrp($fpath, 'nobody');
259
	@chmod($fpath, 0600);
260

    
261
	$conf .= "{$directive} {$fpath} {$opt}\n";
262
}
263

    
264
function openvpn_reconfigure($mode,& $settings) {
265
	global $g, $config;
266

    
267
	if (empty($settings))
268
		return;
269
	if (isset($settings['disable'])) 
270
		return;
271

    
272
	/*
273
	 * NOTE: Deleting tap devices causes spontaneous reboots. Instead,
274
	 * we use a vpnid number which is allocated for a particular client
275
	 * or server configuration. ( see openvpn_vpnid_next() )
276
	 */
277

    
278
	$vpnid = $settings['vpnid'];
279
	$mode_id = $mode.$vpnid;
280

    
281
	if (isset($settings['dev_mode']))
282
		$tunname = "{$settings['dev_mode']}{$vpnid}";
283
	else {	/* defaults to tun */
284
		$tunname = "tun{$vpnid}";
285
		$settings['dev_mode'] = "tun";
286
	}
287

    
288
	if ($mode == "server")
289
		$devname = "ovpns{$vpnid}";
290
	else
291
		$devname = "ovpnc{$vpnid}";
292

    
293
	/* is our device already configured */
294
	if (mwexec("/sbin/ifconfig {$devname}")) {
295

    
296
		/* create the tap device if required */
297
		if (!file_exists("/dev/{$tunname}"))
298
			exec("/sbin/ifconfig {$tunname} create");
299

    
300
		/* rename the device */
301
		mwexec("/sbin/ifconfig {$tunname} name {$devname}");
302

    
303
		/* add the device to the openvpn group */
304
		mwexec("/sbin/ifconfig {$devname} group openvpn");
305
	}
306

    
307
	$pfile = $g['varrun_path'] . "/openvpn_{$mode_id}.pid";
308
	$proto = ($settings['protocol'] == 'UDP' ? 'udp' : "tcp-{$mode}");
309
	$cipher = $settings['crypto'];
310

    
311
	$interface = $settings['interface'];
312
	$ipaddr = $settings['ipaddr'];
313

    
314
	// If a specific ip address (VIP) is requested, use it.
315
	// Otherwise, if a specific interface is requested, use it
316
	// If "any" interface was selected, local directive will be ommited.
317
	if (!empty($ipaddr)) {
318
		$iface_ip=$ipaddr;
319
	} else {
320
		if ((!empty($interface)) && (strcmp($interface, "any"))) {
321
			$iface_ip=get_interface_ip($interface);
322
		}
323
	}
324

    
325
	$conf  = "dev {$devname}\n";
326
	$conf .= "dev-type {$settings['dev_mode']}\n";
327
	$conf .= "dev-node /dev/{$tunname}\n";
328
	$conf .= "writepid {$pfile}\n";
329
	$conf .= "#user nobody\n";
330
	$conf .= "#group nobody\n";
331
	$conf .= "script-security 3\n";
332
	$conf .= "daemon\n";
333
	$conf .= "keepalive 10 60\n";
334
	$conf .= "ping-timer-rem\n";
335
	$conf .= "persist-tun\n";
336
	$conf .= "persist-key\n";
337
	$conf .= "proto {$proto}\n";
338
	$conf .= "cipher {$cipher}\n";
339
	$conf .= "up /usr/local/sbin/ovpn-linkup\n";
340
	$conf .= "down /usr/local/sbin/ovpn-linkdown\n";
341

    
342
	if (!empty($iface_ip)) {
343
		$conf .= "local {$iface_ip}\n";	
344
	}
345

    
346
	// server specific settings
347
	if ($mode == 'server') {
348

    
349
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
350
		$mask = gen_subnet_mask($mask);
351

    
352
		// configure tls modes
353
		switch($settings['mode']) {
354
			case 'p2p_tls':
355
			case 'server_tls':
356
			case 'server_user':
357
			case 'server_tls_user':
358
				$conf .= "tls-server\n";
359
				break;
360
		}
361

    
362
		// configure p2p/server modes
363
		switch($settings['mode']) {
364
			case 'p2p_tls':
365
			case 'p2p_shared_key':
366
				$baselong = ip2long32($ip) & ip2long($mask);
367
				$ip1 = long2ip32($baselong + 1);
368
				$ip2 = long2ip32($baselong + 2);
369
				$conf .= "ifconfig $ip1 $ip2\n";
370
				break;
371
			case 'server_tls':
372
			case 'server_user':
373
			case 'server_tls_user':
374
				$conf .= "server {$ip} {$mask}\n";
375
				$conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
376
				break;
377
		}
378

    
379
		// configure user auth modes
380
		switch($settings['mode']) {
381
			case 'server_user':
382
				$conf .= "client-cert-not-required\n";
383
			case 'server_tls_user':
384
				$conf .= "username-as-common-name\n";
385
				if (!empty($settings['authmode'])) {
386
					$authcfgs = explode(",", $settings['authmode']);
387
					$sed = "\$authmodes=array(";
388
					$firstsed = 0;
389
					foreach ($authcfgs as $authcfg) {
390
						if ($firstsed > 0)
391
							$sed .= ",";
392
						$firstsed = 1;
393
						$sed .= "\"{$authcfg}\"";
394
					}
395
					$sed .= ");\\\n";
396
					if ($settings['strictusercn'])
397
						$sed .= "\$strictusercn = true;";
398
					$sed .= " \$modeid = \"{$mode_id}\";";
399
					mwexec("/bin/cat /etc/inc/openvpn.auth-user.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/openvpn/{$mode_id}.php");
400
					mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.php");
401
					$conf .= "auth-user-pass-verify {$g['varetc_path']}/openvpn/{$mode_id}.php via-env\n";
402
				}
403
				break;
404
		}
405

    
406
		// The local port to listen on
407
		$conf .= "lport {$settings['local_port']}\n";
408

    
409
		// The management port to listen on
410
		// Use unix socket to overcome the problem on any type of server
411
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
412
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
413

    
414
		if ($settings['maxclients'])
415
			$conf .= "max-clients {$settings['maxclients']}\n";
416

    
417
		// Can we push routes
418
		if ($settings['local_network']) {
419
			list($ip, $mask) = explode('/', $settings['local_network']);
420
			$mask = gen_subnet_mask($mask);
421
			$conf .= "push \"route $ip $mask\"\n";
422
		}
423

    
424
		switch($settings['mode']) {
425
			case 'server_tls':
426
			case 'server_user':
427
			case 'server_tls_user':
428
				// Configure client dhcp options
429
				openvpn_add_dhcpopts($settings, $conf);
430
				if ($settings['client2client'])
431
					$conf .= "client-to-client\n";
432
				break;
433
		}
434
	}
435

    
436
	// client specific settings
437

    
438
	if ($mode == 'client') {
439

    
440
		// configure p2p mode
441
		switch($settings['mode']) {
442
			case 'p2p_tls':
443
				$conf .= "tls-client\n";
444
			case 'shared_key':
445
				$conf .= "client\n";
446
				break;
447
		}
448

    
449
		// If there is no bind option at all (ip and/or port), add "nobind" directive
450
		//  Otherwise, use the local port if defined, failing that, use lport 0 to 
451
		//  ensure a random source port.
452
		if ((empty($iface_ip)) && (!$settings['local_port']))
453
			$conf .= "nobind\n";
454
		elseif ($settings['local_port'])
455
			$conf .= "lport {$settings['local_port']}\n";
456
		else
457
			$conf .= "lport 0\n";
458

    
459
		// Use unix socket to overcome the problem on any type of server
460
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
461

    
462
		// The remote server
463
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
464

    
465
		if (!empty($settings['use_shaper']))
466
			$conf .= "shaper {$settings['use_shaper']}\n";
467

    
468
		if (!empty($settings['tunnel_network'])) {
469
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
470
			$mask = gen_subnet_mask($mask);
471
			$baselong = ip2long32($ip) & ip2long($mask);
472
			$ip1 = long2ip32($baselong + 1);
473
			$ip2 = long2ip32($baselong + 2);
474
			$conf .= "ifconfig $ip2 $ip1\n";
475
		}
476

    
477
		if ($settings['proxy_addr']) {
478
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
479
			if ($settings['proxy_authtype'] != "none") {
480
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
481
				$proxypas = "{$settings['proxy_user']}\n";
482
				$proxypas .= "{$settings['proxy_passwd']}\n";
483
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
484
			}
485
			$conf .= " \n";
486
		}
487
	}
488

    
489
	// Add a remote network route if set
490
	if ($settings['remote_network']) {
491
		list($ip, $mask) = explode('/', $settings['remote_network']);
492
		$mask = gen_subnet_mask($mask);
493
		$conf .= "route $ip $mask\n";
494
	}
495

    
496
	// Write the settings for the keys
497
	switch($settings['mode']) {
498
		case 'p2p_shared_key':
499
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
500
			break;
501
		case 'p2p_tls':
502
		case 'server_tls':
503
		case 'server_tls_user':
504
		case 'server_user':
505
			$ca = lookup_ca($settings['caref']);
506
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
507
			$cert = lookup_cert($settings['certref']);
508
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
509
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
510
			if ($mode == 'server')
511
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
512
			if (!empty($settings['crlref'])) {
513
				$crl = lookup_crl($settings['crlref']);
514
				openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify");
515
			}
516
			if ($settings['tls']) {
517
				if (stristr($settings['mode'], "server"))
518
					$tlsopt = 0;
519
				else
520
					$tlsopt = 1;
521
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
522
			}
523
			break;
524
	}
525

    
526
	if ($settings['compression'])
527
		$conf .= "comp-lzo\n";
528

    
529
	if ($settings['passtos'])
530
		$conf .= "passtos\n";
531

    
532
	if ($settings['resolve_retry'])
533
		$conf .= "resolv-retry infinite\n";
534

    
535
	if ($settings['dynamic_ip']) {
536
		$conf .= "persist-remote-ip\n";
537
		$conf .= "float\n";
538
	}
539

    
540
	openvpn_add_custom($settings, $conf);
541

    
542
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
543
	file_put_contents($fpath, $conf);
544
	//chown($fpath, 'nobody');
545
	//chgrp($fpath, 'nobody');
546
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
547
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
548
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
549
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
550
}
551

    
552
function openvpn_restart($mode, & $settings) {
553
	global $g, $config;
554

    
555
	$vpnid = $settings['vpnid'];
556
	$mode_id = $mode.$vpnid;
557

    
558
	/* kill the process if running */
559
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
560
	if (file_exists($pfile)) {
561

    
562
		/* read the pid file */
563
		$pid = rtrim(file_get_contents($pfile));
564
		unlink($pfile);
565

    
566
		/* send a term signal to the process */
567
		posix_kill($pid, SIGTERM);
568

    
569
		/* wait until the process exits */
570
		while(posix_kill($pid, 0))
571
			usleep(250000);
572
	}
573

    
574
	if (isset($settings['disable']))
575
		return;
576

    
577
	/* start the new process */
578
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
579
	mwexec_bg("nohup openvpn --config {$fpath}");
580

    
581
	if (!$g['booting'])
582
		send_event("filter reload");
583
}
584

    
585
function openvpn_delete($mode, & $settings) {
586
	global $g, $config;
587

    
588
	$vpnid = $settings['vpnid'];
589
	$mode_id = $mode.$vpnid;
590

    
591
	$tunname = "tun{$vpnid}";
592
	if ($mode == "server")
593
		$devname = "ovpns{$vpnid}";
594
	else
595
		$devname = "ovpnc{$vpnid}";
596

    
597
	/* kill the process if running */
598
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
599
	if (file_exists($pfile)) {
600

    
601
		/* read the pid file */
602
		$pid = trim(file_get_contents($pfile));
603
		unlink($pfile);
604

    
605
		/* send a term signal to the process */
606
		posix_kill($pid, SIGTERM);
607
	}
608

    
609
	/* remove the device from the openvpn group */
610
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
611

    
612
	/* restore the original adapter name */
613
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
614

    
615
	/* remove the configuration files */
616
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
617
}
618

    
619
function openvpn_resync_csc(& $settings) {
620
	global $g, $config;
621

    
622
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
623

    
624
	if (isset($settings['disable'])) {
625
		unlink_if_exists($fpath);
626
		return;
627
	}
628

    
629
	$conf = '';
630
	if ($settings['block'])
631
		$conf .= "disable\n";
632

    
633
	if ($settings['push_reset'])
634
		$conf .= "push-reset\n";
635

    
636
	if (!empty($settings['tunnel_network'])) {
637
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
638
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
639
		$ip1 = long2ip32($baselong + 1);
640
		$ip2 = long2ip32($baselong + 2);
641
		$conf .= "ifconfig-push {$ip1} {$ip2}\n";
642
	}
643

    
644
	openvpn_add_dhcpopts($settings, $conf);
645

    
646
	if ($settings['gwredir'])
647
		$conf .= "push \"redirect-gateway def1\"\n";
648

    
649
	openvpn_add_custom($settings, $conf);
650

    
651
	file_put_contents($fpath, $conf);
652
	chown($fpath, 'nobody');
653
	chgrp($fpath, 'nobody');
654
}
655

    
656
function openvpn_delete_csc(& $settings) {
657
	global $g, $config;
658

    
659
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
660
	unlink_if_exists($fpath);
661
}
662

    
663
// Resync the configuration and restart the VPN
664
function openvpn_resync($mode, & $settings) {
665
	openvpn_reconfigure($mode, $settings);
666
	openvpn_restart($mode, $settings);
667
}
668

    
669
// Resync and restart all VPNs
670
function openvpn_resync_all($interface = "") {
671
	global $g, $config;
672

    
673
	// delay our setup until the system
674
	// has a chance to init our paths
675
	if (!file_exists($g['varetc_path']."/openvpn") ||
676
		!file_exists($g['varetc_path']."/openvpn-csc"))
677
		return;
678

    
679
	if (!is_array($config['openvpn']))
680
		$config['openvpn'] = array();
681

    
682
/*
683
	if (!$config['openvpn']['dh-parameters']) {
684
		echo "Configuring OpenVPN Parameters ...\n";
685
		$dh_parameters = openvpn_create_dhparams(1024);
686
		$dh_parameters = base64_encode($dh_parameters);
687
		$config['openvpn']['dh-parameters'] = $dh_parameters;
688
		write_config("OpenVPN DH parameters");
689
	}
690

    
691
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
692
	if (!file_exists($path_ovdh)) {
693
		$dh_parameters = $config['openvpn']['dh-parameters'];
694
		$dh_parameters = base64_decode($dh_parameters);
695
		file_put_contents($path_ovdh, $dh_parameters);
696
	}
697
*/
698
	if ($interface <> "")
699
		log_error("Resyncing OpenVPN instances for interface " . convert_friendly_interface_to_friendly_descr($interface) . ".");
700
	else
701
		log_error("Resyncing OpenVPN instances."); 
702

    
703
	if (is_array($config['openvpn']['openvpn-server'])) {
704
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
705
			if ($interface <> "" && $interface != $settings['interface'])
706
				continue;
707
			openvpn_resync('server', $settings);
708
		}
709
	}
710

    
711
	if (is_array($config['openvpn']['openvpn-client'])) {
712
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
713
			if ($interface <> "" && $interface != $settings['interface'])
714
				continue;
715
			openvpn_resync('client', $settings);
716
		}
717
	}
718

    
719
	if (is_array($config['openvpn']['openvpn-csc']))
720
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
721
			openvpn_resync_csc($settings);
722

    
723
}
724

    
725
function openvpn_get_active_servers() {
726
	global $config, $g;
727

    
728
	$servers = array();
729
	if (is_array($config['openvpn']['openvpn-server'])) {
730
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
731
	
732
			$prot = $settings['protocol'];
733
			$port = $settings['local_port'];
734
	
735
			$server = array();
736
			$server['port'] = $settings['local_port'];
737
			$server['mode'] = $settings['mode'];
738
			if ($settings['description'])
739
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
740
			else
741
				$server['name'] = "Server {$prot}:{$port}";
742
			$server['conns'] = array();
743
	
744
			$vpnid = $settings['vpnid'];
745
                        $mode_id = "server{$vpnid}";
746
			$server['mgmt'] = $mode_id;
747
                        $tcpsrv = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
748
			$errval;
749
			$errstr;
750
	
751
			/* open a tcp connection to the management port of each server */
752
			$fp = @stream_socket_client($tcpsrv, $errval, $errstr, 1);
753
			if ($fp) {
754
				stream_set_timeout($fp, 1);
755
	
756
				/* send our status request */
757
				fputs($fp, "status 2\n");
758
	
759
				/* recv all response lines */
760
				while (!feof($fp)) {
761
	
762
					/* read the next line */
763
					$line = fgets($fp, 1024);
764
	
765
					$info = stream_get_meta_data($fp);
766
					if ($info['timed_out'])
767
						break;
768

    
769
					/* parse header list line */
770
					if (strstr($line, "HEADER"))
771
						continue;
772
	
773
					/* parse end of output line */
774
					if (strstr($line, "END") || strstr($line, "ERROR"))
775
						break;
776
	
777
					/* parse client list line */
778
					if (strstr($line, "CLIENT_LIST")) {
779
						$list = explode(",", $line);
780
						$conn = array();
781
						$conn['common_name'] = $list[1];
782
						$conn['remote_host'] = $list[2];
783
						$conn['virtual_addr'] = $list[3];
784
						$conn['bytes_recv'] = $list[4];
785
						$conn['bytes_sent'] = $list[5];
786
						$conn['connect_time'] = $list[6];
787
						$server['conns'][] = $conn;
788
					}
789
				}
790
	
791
				/* cleanup */
792
				fclose($fp);
793
			} else {
794
				$conn = array();
795
				$conn['common_name'] = "[error]";
796
				$conn['remote_host'] = "Management Daemon Unreachable";
797
				$conn['virtual_addr'] = "";
798
				$conn['bytes_recv'] = 0;
799
				$conn['bytes_sent'] = 0;
800
				$conn['connect_time'] = 0;
801
				$server['conns'][] = $conn;
802
			}
803
	
804
			$servers[] = $server;
805
		}
806
	}
807
	return $servers;
808
}
809

    
810
function openvpn_get_active_clients() {
811
	global $config, $g;
812

    
813
	$clients = array();
814
	if (is_array($config['openvpn']['openvpn-client'])) {
815
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
816
	
817
			$prot = $settings['protocol'];
818
			$port = $settings['local_port'];
819
	
820
			$client = array();
821
			$client['port'] = $settings['local_port'];
822
			if ($settings['description'])
823
				$client['name'] = "{$settings['description']} {$prot}:{$port}";
824
			else
825
				$client['name'] = "Client {$prot}:{$port}";
826
	
827
			$vpnid = $settings['vpnid'];
828
        		$mode_id = "client{$vpnid}";
829
			$client['mgmt'] = $mode_id;
830
			$tcpcli = "unix://{$g['varetc_path']}/openvpn/{$mode_id}.sock";
831
			$errval;
832
			$errstr;
833
	
834
			$client['status']="down";
835
	
836
			/* open a tcp connection to the management port of each cli */
837
			$fp = @stream_socket_client($tcpcli, $errval, $errstr, 1);
838
			if ($fp) {
839
				stream_set_timeout($fp, 1);
840
				/* send our status request */
841
				fputs($fp, "state 1\n");
842
	
843
				/* recv all response lines */
844
				while (!feof($fp)) {
845
					/* read the next line */
846
					$line = fgets($fp, 1024);
847
					
848
					$info = stream_get_meta_data($fp);
849
					if ($info['timed_out'])
850
						break;	
851

    
852
					/* Get the client state */
853
					if (strstr($line,"CONNECTED")) {
854
						$client['status']="up";
855
						$list = explode(",", $line);
856
	
857
						$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
858
						$client['virtual_addr']  = $list[3];
859
						$client['remote_host'] = $list[4];
860
					}
861
					/* parse end of output line */
862
					if (strstr($line, "END") || strstr($line, "ERROR"))
863
						break;
864
				}
865
	
866
				/* If up, get read/write stats */
867
				if (strcmp($client['status'], "up") == 0) {
868
					fputs($fp, "status 2\n");
869
					/* recv all response lines */
870
					while (!feof($fp)) {
871
						/* read the next line */
872
						$line = fgets($fp, 1024);
873
	
874
						$info = stream_get_meta_data($fp);
875
						if ($info['timed_out'])
876
							break;	
877

    
878
						if (strstr($line,"TCP/UDP read bytes")) {
879
							$list = explode(",", $line);
880
							$client['bytes_recv'] = $list[1];
881
						}
882
	
883
						if (strstr($line,"TCP/UDP write bytes")) {
884
							$list = explode(",", $line);
885
							$client['bytes_sent'] = $list[1];
886
						}
887
	
888
						/* parse end of output line */
889
						if (strstr($line, "END"))
890
							break;
891
					}
892
				}
893
	
894
				fclose($fp);
895
	
896
			} else {
897
				$DisplayNote=true;
898
				$client['remote_host'] = "No Management Daemon";
899
				$client['virtual_addr'] = "See Note Below";
900
				$client['bytes_recv'] = 0;
901
				$client['bytes_sent'] = 0;
902
				$client['connect_time'] = 0;
903
			}
904
	
905
			$clients[] = $client;
906
		}
907
	}
908
	return $clients;
909
}
910

    
911
function openvpn_refresh_crls() {
912
	global $g, $config;
913

    
914
	if (!file_exists($g['varetc_path']."/openvpn"))
915
		return;
916

    
917
	if (is_array($config['openvpn']['openvpn-server'])) {
918
		foreach ($config['openvpn']['openvpn-server'] as $settings) {
919
			if (empty($settings))
920
				continue;
921
			if (isset($settings['disable']))
922
				continue;
923
			// Write the settings for the keys
924
			switch($settings['mode']) {
925
				case 'p2p_tls':
926
				case 'server_tls':
927
				case 'server_tls_user':
928
				case 'server_user':
929
					if (!empty($settings['crlref'])) {
930
						$crl = lookup_crl($settings['crlref']);
931
						$fpath = $g['varetc_path']."/openvpn/server{$settings['vpnid']}.crl-verify";
932
						file_put_contents($fpath, base64_decode($crl['text']));
933
						@chmod($fpath, 0644);
934
					}
935
					break;
936
			}
937
		}
938
	}
939
}
940

    
941
?>
(29-29/54)