Project

General

Profile

Download (26 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;\n";
398
					$sed .= "putenv(\"LDAPTLS_CACERT={$g['varetc_path']}/openvpn/{$modeid}.ca\");\n";
399
					$sed .= "putenv(\"LDAPTLS_REQCERT=never\");\n";
400
					mwexec("/bin/cat /etc/inc/openvpn.auth-user.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/openvpn/{$mode_id}.php");
401
					mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.php");
402
					$conf .= "auth-user-pass-verify {$g['varetc_path']}/openvpn/{$mode_id}.php via-env\n";
403
				}
404
				break;
405
		}
406

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

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

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

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

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

    
437
	// client specific settings
438

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
541
	openvpn_add_custom($settings, $conf);
542

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
643
	openvpn_add_dhcpopts($settings, $conf);
644

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

    
648
	openvpn_add_custom($settings, $conf);
649

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

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

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

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

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

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

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

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

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

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

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

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

    
722
}
723

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

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

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

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

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

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

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

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

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

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

    
940
?>
(29-29/54)