Project

General

Profile

Download (23.8 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 /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 .= ");";
396
					mwexec("/bin/cat /etc/inc/openvpn.auth-user.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/openvpn/{$mode_id}.php");
397
					mwexec("/bin/chmod a+x {$g['varetc_path']}/openvpn/{$mode_id}.php");
398
					$conf .= "auth-user-pass-verify {$g['varetc_path']}/openvpn/{$mode_id}.php via-env\n";
399
				}
400
				break;
401
		}
402

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

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

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

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

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

    
428
		if ($settings['client2client'])
429
			$conf .= "client-to-client\n";
430
	}
431

    
432
	// client specific settings
433

    
434
	if ($mode == 'client') {
435

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

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

    
452
		// If there is no bind option at all (ip and/or port), add "nobind" directive
453
		if ((empty($iface_ip)) && (!$settings['local_port'])) {
454
			$conf .= "nobind\n";
455
		}
456

    
457
		// The remote server
458
		$conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
459

    
460
		if (!empty($settings['use_shaper']))
461
			$conf .= "shaper {$settings['use_shaper']}\n";
462

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

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

    
484
	// Add a remote network route if set
485
	if ($settings['remote_network']) {
486
		list($ip, $mask) = explode('/', $settings['remote_network']);
487
		$mask = gen_subnet_mask($mask);
488
		$conf .= "route $ip $mask\n";
489
	}
490

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

    
519
	if ($settings['compression'])
520
		$conf .= "comp-lzo\n";
521

    
522
	if ($settings['passtos'])
523
		$conf .= "passtos\n";
524

    
525
	if ($settings['resolve_retry'])
526
		$conf .= "resolv-retry infinite\n";
527

    
528
	if ($settings['dynamic_ip']) {
529
		$conf .= "persist-remote-ip\n";
530
		$conf .= "float\n";
531
	}
532

    
533
	openvpn_add_custom($settings, $conf);
534

    
535
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
536
	file_put_contents($fpath, $conf);
537
	//chown($fpath, 'nobody');
538
	//chgrp($fpath, 'nobody');
539
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
540
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.key", 0600);
541
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.tls-auth", 0600);
542
	@chmod("{$g['varetc_path']}/openvpn/{$mode_id}.conf", 0600);
543
}
544

    
545
function openvpn_restart($mode, & $settings) {
546
	global $g, $config;
547

    
548
	$vpnid = $settings['vpnid'];
549
	$mode_id = $mode.$vpnid;
550

    
551
	/* kill the process if running */
552
	$pfile = $g['varrun_path']."/openvpn_{$mode_id}.pid";
553
	if (file_exists($pfile)) {
554

    
555
		/* read the pid file */
556
		$pid = rtrim(file_get_contents($pfile));
557
		unlink($pfile);
558

    
559
		/* send a term signal to the process */
560
		posix_kill($pid, SIGTERM);
561

    
562
		/* wait until the process exits */
563
		while(posix_kill($pid, 0))
564
			usleep(250000);
565
	}
566

    
567
	if (isset($settings['disable']))
568
		return;
569

    
570
	/* start the new process */
571
	$fpath = $g['varetc_path']."/openvpn/{$mode_id}.conf";
572
	mwexec_bg("nohup openvpn --config {$fpath}");
573
	touch("{$g['tmp_path']}/filter_dirty");
574
}
575

    
576
function openvpn_delete($mode, & $settings) {
577
	global $g, $config;
578

    
579
	$vpnid = $settings['vpnid'];
580
	$mode_id = $mode.$vpnid;
581

    
582
	$tunname = "tun{$vpnid}";
583
	if ($mode == "server")
584
		$devname = "ovpns{$vpnid}";
585
	else
586
		$devname = "ovpnc{$vpnid}";
587

    
588
	/* kill the process if running */
589
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
590
	if (file_exists($pfile)) {
591

    
592
		/* read the pid file */
593
		$pid = trim(file_get_contents($pfile));
594
		unlink($pfile);
595

    
596
		/* send a term signal to the process */
597
		posix_kill($pid, SIGTERM);
598
	}
599

    
600
	/* remove the device from the openvpn group */
601
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
602

    
603
	/* restore the original adapter name */
604
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
605

    
606
	/* remove the configuration files */
607
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
608
}
609

    
610
function openvpn_resync_csc(& $settings) {
611
	global $g, $config;
612

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

    
615
	if (isset($settings['disable'])) {
616
		unlink_if_exists($fpath);
617
		return;
618
	}
619

    
620
	$conf = '';
621
	if ($settings['block'])
622
		$conf .= "disable\n";
623

    
624
	if ($settings['push_reset'])
625
		$conf .= "push-reset\n";
626

    
627
	if (!empty($settings['tunnel_network'])) {
628
		list($ip, $mask) = explode('/', $settings['tunnel_network']);
629
		$baselong = ip2long32($ip) & gen_subnet_mask_long($mask);
630
		$ip1 = long2ip32($baselong + 1);
631
		$ip2 = long2ip32($baselong + 2);
632
		$conf .= "ifconfig-push {$ip1} {$ip2}\n";
633
	}
634

    
635
	openvpn_add_dhcpopts($settings, $conf);
636

    
637
	if ($settings['gwredir'])
638
		$conf .= "push \"redirect-gateway def1\"\n";
639

    
640
	openvpn_add_custom($settings, $conf);
641

    
642
	file_put_contents($fpath, $conf);
643
	chown($fpath, 'nobody');
644
	chgrp($fpath, 'nobody');
645
}
646

    
647
function openvpn_delete_csc(& $settings) {
648
	global $g, $config;
649

    
650
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
651
	unlink_if_exists($fpath);
652
}
653

    
654
// Resync the configuration and restart the VPN
655
function openvpn_resync($mode, & $settings) {
656
	openvpn_reconfigure($mode, $settings);
657
	openvpn_restart($mode, $settings);
658
}
659

    
660
// Resync and restart all VPNs
661
function openvpn_resync_all($interface = "") {
662
	global $g, $config;
663

    
664
	// delay our setup until the system
665
	// has a chance to init our paths
666
	if (!file_exists($g['varetc_path']."/openvpn") ||
667
		!file_exists($g['varetc_path']."/openvpn-csc"))
668
		return;
669

    
670
	if (!is_array($config['openvpn']))
671
		$config['openvpn'] = array();
672

    
673
/*
674
	if (!$config['openvpn']['dh-parameters']) {
675
		echo "Configuring OpenVPN Parameters ...\n";
676
		$dh_parameters = openvpn_create_dhparams(1024);
677
		$dh_parameters = base64_encode($dh_parameters);
678
		$config['openvpn']['dh-parameters'] = $dh_parameters;
679
		write_config("OpenVPN DH parameters");
680
	}
681

    
682
	$path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
683
	if (!file_exists($path_ovdh)) {
684
		$dh_parameters = $config['openvpn']['dh-parameters'];
685
		$dh_parameters = base64_decode($dh_parameters);
686
		file_put_contents($path_ovdh, $dh_parameters);
687
	}
688
*/
689

    
690
	if (is_array($config['openvpn']['openvpn-server'])) {
691
		foreach ($config['openvpn']['openvpn-server'] as & $settings) {
692
			if (!empty($interface) && $interface != $settings['interface'])
693
				continue;
694
			openvpn_resync('server', $settings);
695
		}
696
	}
697

    
698
	if (is_array($config['openvpn']['openvpn-client'])) {
699
		foreach ($config['openvpn']['openvpn-client'] as & $settings) {
700
			if (!empty($interface) && $interface != $settings['interface'])
701
				continue;
702
			openvpn_resync('client', $settings);
703
		}
704
	}
705

    
706
	if (is_array($config['openvpn']['openvpn-csc']))
707
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
708
			openvpn_resync_csc($settings);
709

    
710
}
711

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

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