Project

General

Profile

Download (25 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 .= ");";
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
		// Use unix socket to overcome the problem on any type of server
408
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
409
		//$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
410

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

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

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

    
433
	// client specific settings
434

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

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

    
446
		// The port we'll listen at
447
		// If local_port is used, bind the management port
448
		if ($settings['local_port']) {
449
			$conf .= "lport {$settings['local_port']}\n";
450
		}
451
		// Use unix socket to overcome the problem on any type of server
452
		$conf .= "management {$g['varetc_path']}/openvpn/{$mode_id}.sock unix\n";
453

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

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

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

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

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

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

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

    
523
	if ($settings['compression'])
524
		$conf .= "comp-lzo\n";
525

    
526
	if ($settings['passtos'])
527
		$conf .= "passtos\n";
528

    
529
	if ($settings['resolve_retry'])
530
		$conf .= "resolv-retry infinite\n";
531

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

    
537
	openvpn_add_custom($settings, $conf);
538

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

    
549
function openvpn_restart($mode, & $settings) {
550
	global $g, $config;
551

    
552
	$vpnid = $settings['vpnid'];
553
	$mode_id = $mode.$vpnid;
554

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

    
559
		/* read the pid file */
560
		$pid = rtrim(file_get_contents($pfile));
561
		unlink($pfile);
562

    
563
		/* send a term signal to the process */
564
		posix_kill($pid, SIGTERM);
565

    
566
		/* wait until the process exits */
567
		while(posix_kill($pid, 0))
568
			usleep(250000);
569
	}
570

    
571
	if (isset($settings['disable']))
572
		return;
573

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

    
580
function openvpn_delete($mode, & $settings) {
581
	global $g, $config;
582

    
583
	$vpnid = $settings['vpnid'];
584
	$mode_id = $mode.$vpnid;
585

    
586
	$tunname = "tun{$vpnid}";
587
	if ($mode == "server")
588
		$devname = "ovpns{$vpnid}";
589
	else
590
		$devname = "ovpnc{$vpnid}";
591

    
592
	/* kill the process if running */
593
	$pfile = "{$g['varrun_path']}/openvpn_{$mode_id}.pid";
594
	if (file_exists($pfile)) {
595

    
596
		/* read the pid file */
597
		$pid = trim(file_get_contents($pfile));
598
		unlink($pfile);
599

    
600
		/* send a term signal to the process */
601
		posix_kill($pid, SIGTERM);
602
	}
603

    
604
	/* remove the device from the openvpn group */
605
	mwexec("/sbin/ifconfig {$devname} -group openvpn");
606

    
607
	/* restore the original adapter name */
608
	mwexec("/sbin/ifconfig {$devname} name {$tunname}");
609

    
610
	/* remove the configuration files */
611
	mwexec("/bin/rm {$g['varetc_path']}/openvpn/{$mode_id}.*");
612
}
613

    
614
function openvpn_resync_csc(& $settings) {
615
	global $g, $config;
616

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

    
619
	if (isset($settings['disable'])) {
620
		unlink_if_exists($fpath);
621
		return;
622
	}
623

    
624
	$conf = '';
625
	if ($settings['block'])
626
		$conf .= "disable\n";
627

    
628
	if ($settings['push_reset'])
629
		$conf .= "push-reset\n";
630

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

    
639
	openvpn_add_dhcpopts($settings, $conf);
640

    
641
	if ($settings['gwredir'])
642
		$conf .= "push \"redirect-gateway def1\"\n";
643

    
644
	openvpn_add_custom($settings, $conf);
645

    
646
	file_put_contents($fpath, $conf);
647
	chown($fpath, 'nobody');
648
	chgrp($fpath, 'nobody');
649
}
650

    
651
function openvpn_delete_csc(& $settings) {
652
	global $g, $config;
653

    
654
	$fpath = $g['varetc_path']."/openvpn-csc/".$settings['common_name'];
655
	unlink_if_exists($fpath);
656
}
657

    
658
// Resync the configuration and restart the VPN
659
function openvpn_resync($mode, & $settings) {
660
	openvpn_reconfigure($mode, $settings);
661
	openvpn_restart($mode, $settings);
662
}
663

    
664
// Resync and restart all VPNs
665
function openvpn_resync_all($interface = "") {
666
	global $g, $config;
667

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

    
674
	if (!is_array($config['openvpn']))
675
		$config['openvpn'] = array();
676

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

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

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

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

    
714
	if (is_array($config['openvpn']['openvpn-csc']))
715
		foreach ($config['openvpn']['openvpn-csc'] as & $settings)
716
			openvpn_resync_csc($settings);
717

    
718
}
719

    
720
function openvpn_get_active_servers() {
721
	global $config, $g;
722

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

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

    
805
function openvpn_get_active_clients() {
806
	global $config, $g;
807

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

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

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