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
		switch($settings['mode']) {
420
			case 'server_tls':
421
			case 'server_user':
422
			case 'server_tls_user':
423
				// Configure client dhcp options
424
				openvpn_add_dhcpopts($settings, $conf);
425
				if ($settings['client2client'])
426
					$conf .= "client-to-client\n";
427
				break;
428
		}
429
	}
430

    
431
	// client specific settings
432

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
532
	openvpn_add_custom($settings, $conf);
533

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
634
	openvpn_add_dhcpopts($settings, $conf);
635

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

    
639
	openvpn_add_custom($settings, $conf);
640

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

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

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

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

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

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

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

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

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

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

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

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

    
709
}
710

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

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