Project

General

Profile

Download (23.6 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

    
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 /etc/rc.filter_configure\n";
340
	$conf .= "down /etc/rc.filter_configure\n";
341

    
342
	if (!empty($iface_ip)) {
343
		if ($mode == "server" || ($mode == "client" && !empty($settings['local_port'])))
344
			$conf .= "local {$iface_ip}\n";	
345
	}
346

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

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

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

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

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

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

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

    
410
		if ($settings['maxclients'])
411
			$conf .= "max-clients {$settings['maxclients']}\n";
412

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

    
420
		// Configure client dhcp options
421
		switch($settings['mode']) {
422
			case 'server_tls':
423
			case 'server_user':
424
			case 'server_tls_user':
425
				openvpn_add_dhcpopts($settings, $conf);
426
				break;
427
		}
428
	}
429

    
430
	// client specific settings
431

    
432
	if ($mode == 'client') {
433

    
434
		// configure p2p mode
435
		switch($settings['mode']) {
436
			case 'p2p_tls':
437
				$conf .= "tls-client\n";
438
			case 'shared_key':
439
				$conf .= "client\n";
440
				break;
441
		}
442

    
443
		// The port we'll listen at
444
		// If local_port is used, bind the management port
445
		if ($settings['local_port']) {
446
			$conf .= "lport {$settings['local_port']}\n";
447
			$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
448
		}
449
		else
450
			$conf .= "nobind\n";
451

    
452
		// The remote server
453
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
454

    
455
		if (!empty($settings['use_shaper']))
456
			$conf .= "shaper {$settings['use_shaper']}\n";
457

    
458
		if (!empty($settings['tunnel_network'])) {
459
			list($ip, $mask) = explode('/', $settings['tunnel_network']);
460
			$mask = gen_subnet_mask($mask);
461
			$baselong = ip2long($ip) & ip2long($mask);
462
			$ip1 = long2ip($baselong + 1);
463
			$ip2 = long2ip($baselong + 2);
464
			$conf .= "ifconfig $ip2 $ip1\n";
465
		}
466

    
467
		if ($settings['proxy_addr']) {
468
			$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}";
469
			if ($settings['proxy_authtype'] != "none") {
470
				$conf .= " {$g['varetc_path']}/openvpn/{$mode_id}.pas {$settings['proxy_authtype']}";
471
				$proxypas = "{$settings['proxy_user']}\n";
472
				$proxypas .= "{$settings['proxy_passwd']}\n";
473
				file_put_contents("{$g['varetc_path']}/openvpn/{$mode_id}.pas", $proxypas);
474
			}
475
			$conf .= " \n";
476
		}
477
	}
478

    
479
	// Add a remote network route if set
480
	if ($settings['remote_network']) {
481
		list($ip, $mask) = explode('/', $settings['remote_network']);
482
		$mask = gen_subnet_mask($mask);
483
		$conf .= "route $ip $mask\n";
484
	}
485

    
486
	// Write the settings for the keys
487
	switch($settings['mode']) {
488
		case 'p2p_shared_key':
489
			openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
490
			break;
491
		case 'p2p_tls':
492
		case 'server_tls':
493
		case 'server_tls_user':
494
		case 'server_user':
495
			$ca = lookup_ca($settings['caref']);
496
			openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
497
			$cert = lookup_cert($settings['certref']);
498
			openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
499
			openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
500
			if ($mode == 'server')
501
				$conf .= "dh {$g['etc_path']}/dh-parameters.{$settings['dh_length']}\n";
502
			if ($settings['crl'])
503
				openvpn_add_keyfile($settings['crl'], $conf, $mode_id, "crl-verify");
504
			if ($settings['tls']) {
505
				if (stristr($settings['mode'], "server"))
506
					$tlsopt = 0;
507
				else
508
					$tlsopt = 1;
509
				openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt);
510
			}
511
			break;
512
	}
513

    
514
	if ($settings['compression'])
515
		$conf .= "comp-lzo\n";
516

    
517
	if ($settings['passtos'])
518
		$conf .= "passtos\n";
519

    
520
	if ($settings['resolve_retry'])
521
		$conf .= "resolv-retry infinite\n";
522

    
523
	if ($settings['dynamic_ip']) {
524
		$conf .= "persist-remote-ip\n";
525
		$conf .= "float\n";
526
	}
527

    
528
	openvpn_add_custom($settings, $conf);
529

    
530
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
531
	file_put_contents($fpath, $conf);
532
	//chown($fpath, 'nobody');
533
	//chgrp($fpath, 'nobody');
534
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
535
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
536
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
537
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
538
}
539

    
540
function openvpn_restart($mode, & $settings) {
541
	global $g, $config;
542

    
543
	$vpnid = $settings['vpnid'];
544
	$mode_id = $mode.$vpnid;
545

    
546
	/* kill the process if running */
547
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
548
	if (file_exists($pfile)) {
549

    
550
		/* read the pid file */
551
		$pid = rtrim(file_get_contents($pfile));
552
		unlink($pfile);
553

    
554
		/* send a term signal to the process */
555
		posix_kill($pid, SIGTERM);
556

    
557
		/* wait until the process exits */
558
		while(posix_kill($pid, 0))
559
			usleep(250000);
560
	}
561

    
562
	if (isset($settings['disable']))
563
		return;
564

    
565
	/* start the new process */
566
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
567
	mwexec_bg("nohup openvpn --config {$fpath}");
568
	touch("{$g['tmp_path']}/filter_dirty");
569
}
570

    
571
function openvpn_delete($mode, & $settings) {
572
	global $g, $config;
573

    
574
	$vpnid = $settings['vpnid'];
575
	$mode_id = $mode.$vpnid;
576

    
577
	$tunname = "tun{$vpnid}";
578
	if ($mode == "server")
579
		$devname = "ovpns{$vpnid}";
580
	else
581
		$devname = "ovpnc{$vpnid}";
582

    
583
	/* kill the process if running */
584
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
585
	if (file_exists($pfile)) {
586

    
587
		/* read the pid file */
588
		$pid = trim(file_get_contents($pfile));
589
		unlink($pfile);
590

    
591
		/* send a term signal to the process */
592
		posix_kill($pid, SIGTERM);
593
	}
594

    
595
	/* remove the device from the openvpn group */
596
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
597

    
598
	/* restore the original adapter name */
599
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
600

    
601
	/* remove the configuration files */
602
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
603
}
604

    
605
function openvpn_resync_csc(& $settings) {
606
	global $g, $config;
607

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

    
610
	if (isset($settings['disable'])) {
611
		unlink_if_exists($fpath);
612
		return;
613
	}
614

    
615
	$conf = '';
616
	if ($settings['block'])
617
		$conf .= "disable\n";
618

    
619
	if ($settings['push_reset'])
620
		$conf .= "push-reset\n";
621

    
622
	if (!empty($settings['tunnel_network'])) {
623
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
624
		$baselong = ip2long($ip) & gen_subnet_mask_long($mask);
625
		$ip1 = long2ip($baselong + 1);
626
		$ip2 = long2ip($baselong + 2);
627
		$conf .= "ifconfig-push {$ip1} {$ip2}\n";
628
	}
629

    
630
	openvpn_add_dhcpopts($settings, $conf);
631

    
632
	if ($settings['gwredir'])
633
		$conf .= "push \"redirect-gateway def1\"\n";
634

    
635
	openvpn_add_custom($settings, $conf);
636

    
637
	file_put_contents($fpath, $conf);
638
	chown($fpath, 'nobody');
639
	chgrp($fpath, 'nobody');
640
}
641

    
642
function openvpn_delete_csc(& $settings) {
643
	global $g, $config;
644

    
645
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
646
	unlink_if_exists($fpath);
647
}
648

    
649
// Resync the configuration and restart the VPN
650
function openvpn_resync($mode, & $settings) {
651
	openvpn_reconfigure($mode, $settings);
652
	openvpn_restart($mode, $settings);
653
}
654

    
655
// Resync and restart all VPNs
656
function openvpn_resync_all($interface = "") {
657
	global $g, $config;
658

    
659
	// delay our setup until the system
660
	// has a chance to init our paths
661
	if (!file_exists($g['varetc_path']."/openvpn") ||
662
		!file_exists($g['varetc_path']."/openvpn-csc"))
663
		return;
664

    
665
	if (!is_array($config['openvpn']))
666
		$config['openvpn'] = array();
667

    
668
/*
669
	if (!$config['openvpn']['dh-parameters']) {
670
		echo "Configuring OpenVPN Parameters ...\n";
671
		$dh_parameters = openvpn_create_dhparams(1024);
672
		$dh_parameters = base64_encode($dh_parameters);
673
		$config['openvpn']['dh-parameters'] = $dh_parameters;
674
		write_config("OpenVPN DH parameters");
675
	}
676

    
677
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
678
	if (!file_exists($path_ovdh)) {
679
		$dh_parameters = $config['openvpn']['dh-parameters'];
680
		$dh_parameters = base64_decode($dh_parameters);
681
		file_put_contents($path_ovdh, $dh_parameters);
682
	}
683
*/
684

    
685
	if (is_array($config['openvpn']['openvpn-server'])) {
686
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
687
			if (!empty($interface) && $interface != $settings['interface'])
688
				continue;
689
			openvpn_resync('server', $settings);
690
		}
691
	}
692

    
693
	if (is_array($config['openvpn']['openvpn-client'])) {
694
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
695
			if (!empty($interface) && $interface != $settings['interface'])
696
				continue;
697
			openvpn_resync('client', $settings);
698
		}
699
	}
700

    
701
	if (is_array($config['openvpn']['openvpn-csc']))
702
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
703
			openvpn_resync_csc($settings);
704

    
705
}
706

    
707
function openvpn_get_active_servers() {
708
	$servers = array();
709
	global $config;
710
	if (is_array($config['openvpn']['openvpn-server'])) {
711
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
712
	
713
			$prot = $settings['protocol'];
714
			$port = $settings['local_port'];
715
	
716
			$server = array();
717
			$server['port'] = $settings['local_port'];
718
			if ($settings['description'])
719
				$server['name'] = "{$settings['description']} {$prot}:{$port}";
720
			else
721
				$server['name'] = "Server {$prot}:{$port}";
722
			$server['conns'] = array();
723
	
724
			$tcpsrv = "tcp://127.0.0.1:{$port}";
725
			$errval;
726
			$errstr;
727
	
728
			/* open a tcp connection to the management port of each server */
729
			$fp = @stream_socket_client($tcpsrv, $errval, $errstr, 1);
730
			if ($fp) {
731
	
732
				/* send our status request */
733
				fputs($fp, "status 2\n");
734
	
735
				/* recv all response lines */
736
				while (!feof($fp)) {
737
	
738
					/* read the next line */
739
					$line = fgets($fp, 1024);
740
	
741
					/* parse header list line */
742
					if (strstr($line, "HEADER"))
743
						continue;
744
	
745
					/* parse end of output line */
746
					if (strstr($line, "END"))
747
						break;
748
	
749
					/* parse client list line */
750
					if (strstr($line, "CLIENT_LIST")) {
751
						$list = explode(",", $line);
752
						$conn = array();
753
						$conn['common_name'] = $list[1];
754
						$conn['remote_host'] = $list[2];
755
						$conn['virtual_addr'] = $list[3];
756
						$conn['bytes_recv'] = $list[4];
757
						$conn['bytes_sent'] = $list[5];
758
						$conn['connect_time'] = $list[6];
759
						$server['conns'][] = $conn;
760
					}
761
				}
762
	
763
				/* cleanup */
764
				fclose($fp);
765
			} else {
766
				$conn = array();
767
				$conn['common_name'] = "[error]";
768
				$conn['remote_host'] = "Management Daemon Unreachable";
769
				$conn['virtual_addr'] = "";
770
				$conn['bytes_recv'] = 0;
771
				$conn['bytes_sent'] = 0;
772
				$conn['connect_time'] = 0;
773
				$server['conns'][] = $conn;
774
			}
775
	
776
			$servers[] = $server;
777
		}
778
	}
779
	return $servers;
780
}
781

    
782
function openvpn_get_active_clients() {
783
	$clients = array();
784
	global $config;
785
	if (is_array($config['openvpn']['openvpn-client'])) {
786
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
787
	
788
			$prot = $settings['protocol'];
789
			$port = $settings['local_port'];
790
	
791
			$client = array();
792
			$client['port'] = $settings['local_port'];
793
			if ($settings['description'])
794
				$client['name'] = "{$settings['description']} {$prot}:{$port}";
795
			else
796
				$client['name'] = "Client {$prot}:{$port}";
797
	
798
			$tcpcli = "tcp://127.0.0.1:{$port}";
799
			$errval;
800
			$errstr;
801
	
802
			$client['status']="down";
803
	
804
			/* open a tcp connection to the management port of each cli */
805
			$fp = @stream_socket_client($tcpcli, $errval, $errstr, 1);
806
			if ($fp) {
807
	
808
				/* send our status request */
809
				fputs($fp, "state 1\n");
810
	
811
				/* recv all response lines */
812
				while (!feof($fp)) {
813
					/* read the next line */
814
					$line = fgets($fp, 1024);
815
	
816
					/* Get the client state */
817
					if (strstr($line,"CONNECTED")) {
818
						$client['status']="up";
819
						$list = explode(",", $line);
820
	
821
						$client['connect_time']  = date("D M j G:i:s Y", $list[0]);
822
						$client['virtual_addr']  = $list[3];
823
						$client['remote_host'] = $list[4];
824
					}
825
					/* parse end of output line */
826
					if (strstr($line, "END"))
827
						break;
828
				}
829
	
830
				/* If up, get read/write stats */
831
				if (strcmp($client['status'], "up") == 0) {
832
					fputs($fp, "status 2\n");
833
					/* recv all response lines */
834
					while (!feof($fp)) {
835
						/* read the next line */
836
						$line = fgets($fp, 1024);
837
	
838
						if (strstr($line,"TCP/UDP read bytes")) {
839
							$list = explode(",", $line);
840
							$client['bytes_recv'] = $list[1];
841
						}
842
	
843
						if (strstr($line,"TCP/UDP write bytes")) {
844
							$list = explode(",", $line);
845
							$client['bytes_sent'] = $list[1];
846
						}
847
	
848
						/* parse end of output line */
849
						if (strstr($line, "END"))
850
							break;
851
					}
852
				}
853
	
854
				fclose($fp);
855
	
856
			} else {
857
				$DisplayNote=true;
858
				$client['remote_host'] = "No Management Daemon";
859
				$client['virtual_addr'] = "See Note Below";
860
				$client['bytes_recv'] = 0;
861
				$client['bytes_sent'] = 0;
862
				$client['connect_time'] = 0;
863
			}
864
	
865
			$clients[] = $client;
866
		}
867
	}
868
	return $clients;
869
}
870
?>
(28-28/50)