Project

General

Profile

Download (27.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/* $Id$ */
4
/*
5
	$RCSfile$
6
	Copyright (C) 2006  Fernando Lemos
7
	All rights reserved.
8

    
9
	Copyright (C) 2005 Peter Allgeyer <allgeyer_AT_web.de>
10
	All rights reserved.
11

    
12
	Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
13
	All rights reserved.
14

    
15
	Redistribution and use in source and binary forms, with or without
16
	modification, are permitted provided that the following conditions are met:
17

    
18
	1. Redistributions of source code must retain the above copyright notices,
19
	   this list of conditions and the following disclaimer.
20

    
21
	2. Redistributions in binary form must reproduce the above copyright
22
	   notices, this list of conditions and the following disclaimer in the
23
	   documentation and/or other materials provided with the distribution.
24

    
25
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
26
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
29
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
	POSSIBILITY OF SUCH DAMAGE.
35
*/
36

    
37
require_once('config.inc');
38
require_once('pfsense-utils.inc');
39
require_once('util.inc');
40

    
41
// Return the list of ciphers OpenVPN supports
42
function openvpn_get_ciphers($pkg) {
43
	global $config;
44

    
45
	foreach ($pkg['fields']['field'] as $i => $field) {
46
		if ($field['fieldname'] == 'crypto') {
47
			$option_array = &$pkg['fields']['field'][$i]['options']['option'];
48
			$ciphers_out = shell_exec('openvpn --show-ciphers | grep "default key" | awk \'{print $1, "(" $2 "-" $3 ")";}\'');
49
			$ciphers = explode("\n", trim($ciphers_out));
50
			sort($ciphers);
51
			foreach ($ciphers as $cipher) {
52
				$value = explode(' ', $cipher);
53
				$value = $value[0];
54
				$option_array[] = array('value' => $value, 'name' => $cipher);
55
			}
56
		} 
57
		if ($field['fieldname'] == 'cipher') {
58
		        if (is_array($config['openvpn']['keys'])) {
59
                		if (count($config['openvpn']['keys']) > 0) {
60
					$option_array = &$pkg['fields']['field'][$i]['options']['option'];
61
                        		foreach ($config['openvpn']['keys'] as $cipher => $type) {
62
						if ($type['shared.key'])
63
							$option_array[] = array('value' => $cipher, 'name' => $cipher);
64
                       			}
65
                		}
66
        		}
67
		}
68
                if ($field['fieldname'] == 'cipherpki') {
69
                        if (is_array($config['openvpn']['keys'])) {
70
                                if (count($config['openvpn']['keys']) > 0) {
71
                                        $option_array = &$pkg['fields']['field'][$i]['options']['option'];
72
                                        foreach ($config['openvpn']['keys'] as $cipher => $type) {
73
                                                if ($type['auth_method'] == 'pki')
74
                                                        $option_array[] = array('value' => $cipher, 'name' => $cipher);
75
                                        }
76
                                }
77
                        }
78
                }
79

    
80
	}
81
}
82

    
83

    
84
function openvpn_validate_port($value, $name) {
85
	$value = trim($value);
86
	if (!empty($value) && !(is_numeric($value) && ($value > 0) && ($value < 65535)))
87
		return "The field '$name' must contain a valid port, ranging from 0 to 65535.";
88
	return false;
89
}
90

    
91

    
92
function openvpn_validate_cidr($value, $name) {
93
	$value = trim($value);
94
	if (!empty($value)) {
95
		list($ip, $mask) = explode('/', $value);
96
		if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
97
			return "The field '$name' must contain a valid CIDR range.";
98
	}
99
	return false;
100
}
101

    
102

    
103
// Do the input validation
104
function openvpn_validate_input($mode, $post, $input_errors) {
105
	$Mode = ucfirst($mode);
106

    
107
	if ($mode == 'server') {
108
		if ($result = openvpn_validate_port($post['local_port'], 'Local port'))
109
			$input_errors[] = $result;
110

    
111
		if ($result = openvpn_validate_cidr($post['addresspool'], 'Address pool'))
112
			$input_errors[] = $result;
113

    
114
		if ($result = openvpn_validate_cidr($post['local_network'], 'Local network'))
115
			$input_errors[] = $result;
116
			
117
/*  check for port in use - update of existing entries not possible because $_GET['act'] is not passed from pkg_edit.php :-( mfuchs		
118
    $portinuse = shell_exec('sockstat | grep '.$post['local_port'].' | grep '.strtolower($post['protocol']));
119
    if (!empty($portinuse))
120
    $input_errors[] = 'The port '.$post['local_port'].'/'.strtolower($post['protocol']).' is already in use.';
121
*/
122

    
123
	if (!empty($post['dhcp_dns'])) {
124
    $servers = explode(';', $post['dhcp_dns']);
125
      foreach ($servers as $server) if (!is_ipaddr($server))
126
        {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
127
        break;}}
128
	if (!empty($post['dhcp_wins'])) {
129
    $servers = explode(';', $post['dhcp_wins']);
130
      foreach ($servers as $server) if (!is_ipaddr($server))
131
        {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
132
        break;}}
133
	if (!empty($post['dhcp_nbdd'])) {
134
    $servers = explode(';', $post['dhcp_nbdd']);
135
      foreach ($servers as $server) if (!is_ipaddr($server))
136
        {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
137
        break;}}
138
	if (!empty($post['dhcp_ntp'])) {
139
    $servers = explode(';', $post['dhcp_ntp']);
140
      foreach ($servers as $server) if (!is_ipaddr($server))
141
        {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
142
        break;}}
143
	if (isset($post['maxclients']) && $post['maxclients'] != "") {
144
		if (!is_numeric($post['maxclients']))
145
			$input_errors[] = 'The field \'Maximum clients\' must be numeric.';
146
		}
147

    
148
	}
149

    
150
	else { // Client mode
151
		if ($result = openvpn_validate_port($post['serverport'], 'Server port'))
152
			$input_errors[] = $result;
153

    
154
		$server_addr = trim($post['serveraddr']);
155
		if (!empty($value) && !(is_domain($server_addr) || is_ipaddr($server_addr)))
156
			$input_errors[] = 'The field \'Server address\' must contain a valid IP address or domain name.';
157

    
158
		if ($result = openvpn_validate_cidr($post['interface_ip'], 'Interface IP'))
159
			$input_errors[] = $result;
160

    
161
		if ($post['auth_method'] == 'shared_key') {
162
			if (empty($post['interface_ip']))
163
				$input_errors[] = 'The field \'Interface IP\' is required.';
164
		}
165
		if (isset($post['proxy_hostname']) && $post['proxy_hostname'] != "") {
166
			if (!is_domain($post['proxy_hostname']) || is_ipaddr($post['proxy_hostname']))
167
				$input_errors[] = 'The field \'Proxy Host\' must contain a valid IP address or domain name.';
168
			if (!is_port($post['proxy_port']))
169
				$input_errors[] = 'The field \'Proxy port\' must contain a valid port number.';
170
			if ($post['protocol'] != "TCP")
171
				$input_errors[] = 'The protocol must be TCP to use a HTTP proxy server.';
172
		}
173
		if (isset($post['use_shaper']) && $post['use_shaper'] != "") {
174
			if (!is_numeric($post['use_shaper']))
175
				$input_errors[] = 'The field \'Limit outgoing bandwidth\' must be numeric.';
176
		}
177

    
178
	}
179

    
180
	if ($result = openvpn_validate_cidr($post['remote_network'], 'Remote network'))
181
		$input_errors[] = $result;
182

    
183
/* This are no more needed comment them from now and remove later */
184
/*
185
	if ($_POST['auth_method'] == 'shared_key') {
186
		$reqfields[] = 'shared_key';
187
		$reqfieldsn[] = 'Shared key';
188
	}
189
	else {
190
		$req = explode(' ', "ca_cert {$mode}_cert {$mode}_key");
191
		$reqn = array(	'CA certificate',
192
				ucfirst($mode) . ' certificate',
193
				ucfirst($mode) . ' key');
194
		$reqfields = array_merge($reqfields, $req);
195
		$reqfieldsn = array_merge($reqfieldsn, $reqn);
196
		if ($mode == 'server') {
197
			$reqfields[] = 'dh_params';
198
			$reqfieldsn[] = 'DH parameters';
199
		}
200
	}
201
	do_input_validation($post, $reqfields, $reqfieldsn, &$input_errors);
202
*/
203
if ($mode != "server") {
204
	$value = trim($post['shared_key']);
205
	$items = array();
206

    
207
	if ($_POST['auth_method'] == 'shared_key') {
208
		$items[] = array(	'field' => 'shared.key',
209
					'string' => 'OpenVPN Static key V1',
210
					'name' => 'Shared key');
211
	}
212
	else {
213
		$items[] = array(	'field' => 'ca.crt',
214
					'string' => 'CERTIFICATE',
215
					'name' => 'CA certificate');
216
		$items[] = array(	'field' => "{$mode}.crt",
217
					'string' => 'CERTIFICATE',
218
					'name' => "$Mode certificate");
219
		$items[] = array(	'field' => "{$mode}.key",
220
					'string' => 'RSA PRIVATE KEY',
221
					'name' => "$Mode key");
222
	  $items[] = array(	'field' => 'tls',
223
		      'string' => 'OpenVPN Static key V1',
224
		      'name' => 'TLS');
225
		if ($mode == 'server') {
226
			$items[] = array(	'field' => 'dh_param.dhs',
227
						'string' => 'DH PARAMETERS',
228
						'name' => 'DH parameters');
229
			$items[] = array(	'field' => 'crl.crl',
230
						'string' => 'X509 CRL',
231
						'name' => 'CRL');
232
		}
233
	}
234
	foreach ($items as $item) {
235
		$value = trim($_POST[$item['field']]);
236
		$string = $item['string'];
237
		if ($value && (!strstr($value, "-----BEGIN {$string}-----") || !strstr($value, "-----END {$string}-----")))
238
			$input_errors[] = "The field '{$item['name']}' does not appear to be valid";
239
	}
240
}
241
}
242

    
243

    
244
function openvpn_validate_input_csc($post, $input_errors) {
245
	if ($result = openvpn_validate_cidr($post['ifconfig_push'], 'Interface IP'))
246
		$input_errors[] = $result;
247

    
248
	if ($post['push_reset'] != 'on') {
249
    if (!empty($post['dhcp_domainname']))
250
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
251
    elseif (!empty($post['dhcp_dns']))
252
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
253
    elseif (!empty($post['dhcp_wins']))
254
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
255
    elseif (!empty($post['dhcp_nbdd']))
256
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
257
    elseif (!empty($post['dhcp_ntp']))
258
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
259
    elseif ($post['dhcp_nbttype'])
260
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
261
    elseif (!empty($post['dhcp_nbtscope']))
262
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
263
    elseif ($post['dhcp_nbtdisable'])
264
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
265

    
266
  }
267
  else {
268

    
269
	if (!empty($post['dhcp_dns'])) {
270
    $servers = explode(';', $post['dhcp_dns']);
271
      foreach ($servers as $server) if (!is_ipaddr($server))
272
        {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
273
        break;}}
274
	if (!empty($post['dhcp_wins'])) {
275
    $servers = explode(';', $post['dhcp_wins']);
276
      foreach ($servers as $server) if (!is_ipaddr($server))
277
        {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
278
        break;}}
279
	if (!empty($post['dhcp_nbdd'])) {
280
    $servers = explode(';', $post['dhcp_nbdd']);
281
      foreach ($servers as $server) if (!is_ipaddr($server))
282
        {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
283
        break;}}
284
	if (!empty($post['dhcp_ntp'])) {
285
    $servers = explode(';', $post['dhcp_ntp']);
286
      foreach ($servers as $server) if (!is_ipaddr($server))
287
        {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
288
        break;}}
289

    
290
}}
291

    
292
// Rewrite the settings
293
function openvpn_reconfigure($mode, $id) {
294
	global $g, $config;
295

    
296
	$settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
297
	if ($settings['disable']) return;
298

    
299
	$lport = 1194 + $id;
300

    
301
	/*
302
	 * NOTE: if you change the name of the interfaces here than
303
	 * be sure to change it even on the openvpn command parameters at
304
	 * openvpn_restart() function.
305
	 */
306
	if (!$g['booting'])
307
		mwexec("/sbin/ifconfig openvpn{$id} destroy");
308
	mwexec("/sbin/ifconfig tun{$id} create");
309
	mwexec("/sbin/ifconfig tun{$id} name openvpn{$id}");
310
	mwexec("/sbin/ifconfig openvpn{$id} group openvpn");
311

    
312
        $pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
313
        $proto = ($settings['protocol'] == 'UDP' ? 'udp' : "tcp-{$mode}");
314
        $cipher = $settings['crypto'];
315
	$openvpn_conf = "dev openvpn{$id}\n";
316
	$openvpn_conf .= "dev-type tun\n";
317
	$openvpn_conf .= "dev-node /dev/tun{$id}\n";
318
        $openvpn_conf .= <<<EOD
319
writepid $pidfile
320
#user nobody
321
#group nobody
322
daemon
323
keepalive 10 60
324
ping-timer-rem
325
persist-tun
326
persist-key
327
proto $proto
328
cipher $cipher
329
up /etc/rc.filter_configure
330
down /etc/rc.filter_configure
331

    
332
EOD;
333

    
334
	// Mode-specific stuff
335
	if ($mode == 'server') {
336
		list($ip, $mask) = explode('/', $settings['addresspool']);
337
		$mask = gen_subnet_mask($mask);
338

    
339
		// Using a shared key or not dynamically assigning IPs to the clients
340
		if (($settings['auth_method'] == 'shared_key') || ($settings['nopool'] == 'on')) {
341
			if ($settings['auth_method'] == 'pki') $openvpn_conf .= "tls-server\n";
342

    
343
			$baselong = ip2long($ip) & ip2long($mask);
344
			$ip1 = long2ip($baselong + 1);
345
			$ip2 = long2ip($baselong + 2);
346
			$openvpn_conf .= "ifconfig $ip1 $ip2\n";
347
		}
348
		// Using a PKI
349
		else if ($settings['auth_method'] == 'pki') {
350
			if ($settings['client2client']) $openvpn_conf .= "client-to-client\n";
351
			$openvpn_conf .= "server $ip $mask\n";
352
			$csc_dir = "{$g['varetc_path']}/openvpn_csc";
353
			$openvpn_conf .= "client-config-dir $csc_dir\n";
354
		}
355

    
356
		// We can push routes
357
		if (!empty($settings['local_network'])) {
358
			list($ip, $mask) = explode('/', $settings['local_network']);
359
			$mask = gen_subnet_mask($mask);
360
			$openvpn_conf .= "push \"route $ip $mask\"\n";
361
		}
362

    
363
        if ($settings['bind_to_iface'] == 'on') {
364
            $iface = $settings['interface'];
365
            $iface = convert_friendly_interface_to_real_interface_name($iface);
366
            $line = trim(shell_exec("ifconfig $iface | grep inet | grep -v inet6"));
367
            list($dummy, $ip, $dummy2, $dummy3) = explode(' ', $line);
368

    
369
            $openvpn_conf .= "local {$ip}\n";
370
        }
371

    
372
		// The port we'll listen at
373
		$openvpn_conf .= "lport {$settings['local_port']}\n";
374

    
375
		// DHCP-Options
376
	  if (!empty($settings['dhcp_domainname'])) $openvpn_conf .= "push \"dhcp-option DOMAIN {$settings['dhcp_domainname']}\"\n";
377

    
378
    if (!empty($settings['dhcp_dns'])) {
379
	   	$servers = explode(';', $settings['dhcp_dns']);
380
   	  if (is_array($servers)) {
381
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option DNS {$server}\"\n";
382
  	  }
383
		  else {
384
			$openvpn_conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
385
		  }
386
    }
387

    
388
    if (!empty($settings['dhcp_wins'])) {
389
	   	$servers = explode(';', $settings['dhcp_wins']);
390
   	  if (is_array($servers)) {
391
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option WINS {$server}\"\n";
392
  	  }
393
		  else {
394
			$openvpn_conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
395
		  }
396
    }
397

    
398
    if (!empty($settings['dhcp_nbdd'])) {
399
	   	$servers = explode(';', $settings['dhcp_nbdd']);
400
   	  if (is_array($servers)) {
401
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NBDD {$server}\"\n";
402
  	  }
403
		  else {
404
			$openvpn_conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
405
		  }
406
    }
407

    
408
    if (!empty($settings['dhcp_ntp'])) {
409
	   	$servers = explode(';', $settings['dhcp_ntp']);
410
   	  if (is_array($servers)) {
411
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NTP {$server}\"\n";
412
  	  }
413
		  else {
414
			$openvpn_conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
415
		  }
416
    }
417

    
418
  	if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $openvpn_conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
419
    if (!empty($settings['dhcp_nbtscope'])) $openvpn_conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
420
   	if ($settings['dhcp_nbtdisable']) $openvpn_conf .= "push \"dhcp-option DISABLE-NBT\"\n";
421

    
422
    if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_server{$id}.tls 0\n";
423
		if (!empty($settings['maxclients'])) $openvpn_conf .= "max-clients {$settings['maxclients']}\n";
424
		if ($settings['gwredir']) $openvpn_conf .= "push \"redirect-gateway def1\"\n";
425
			}
426

    
427
	else { // $mode == client
428
		// The remote server
429
		$openvpn_conf .= "remote {$settings['serveraddr']} {$settings['serverport']}\n";
430

    
431
		if ($settings['auth_method'] == 'pki') $openvpn_conf .= "client\n";
432
		if ($settings['use_dynamicport']) $openvpn_conf .= "nobind\n";
433
			else
434
			// The port we'll listen at
435
			$openvpn_conf .= "lport {$lport}\n";
436

    
437
		if (!empty($settings['use_shaper'])) $openvpn_conf .= "shaper {$settings['use_shaper']}\n";
438

    
439
		if (!empty($settings['interface_ip'])) {
440
			// Configure the IPs according to the address pool
441
			list($ip, $mask) = explode('/', $settings['interface_ip']);
442
			$mask = gen_subnet_mask($mask);
443
			$baselong = ip2long($ip) & ip2long($mask);
444
			$ip1 = long2ip($baselong + 1);
445
			$ip2 = long2ip($baselong + 2);
446
			$openvpn_conf .= "ifconfig $ip2 $ip1\n";
447
		}
448
		if (isset($settings['proxy_hostname']) && $settings['proxy_hostname'] != "") {
449
			/* ;http-proxy-retry # retry on connection failures */
450
			$openvpn_conf .= "http-proxy {$settings['proxy_hostname']} {$settings['proxy_port']}\n";
451
		}
452

    
453
    if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_client{$id}.tls 1\n";
454

    
455
	}
456

    
457
	// Add the routes if they're set
458
	if (!empty($settings['remote_network'])) {
459
		list($ip, $mask) = explode('/', $settings['remote_network']);
460
		$mask = gen_subnet_mask($mask);
461
		$openvpn_conf .= "route $ip $mask\n";
462
	}
463

    
464
        // Write the settings for the keys
465
        // Set the keys up
466
        $base_file = $g['varetc_path'] . "/openvpn/certificates/";
467
        $keys = array();
468
        if ($settings['auth_method'] == 'shared_key')
469
                $keys[] = array('field' => 'shared.key', 'ext'  => 'secret', 'directive' => 'secret');
470
        else {
471
                $keys[] = array('field' => 'ca.crt', 'directive' => 'ca');
472
                $keys[] = array('field' => "{$mode}.crt", 'directive' => 'cert');
473
                $keys[] = array('field' => "{$mode}.key", 'directive' => 'key');
474
                if ($mode == 'server')
475
                        $keys[] = array('field' => 'dh_params.dh', 'directive' => 'dh');
476
                if ($settings['crl'])
477
                        $keys[] = array('field' => 'crl.crl', 'directive' => 'crl-verify');
478
        }
479

    
480
        foreach ($keys as $key) {
481
                if ($mode == "server") {
482
			if ($settings['auth_method'] == 'pki' && isset($settings['cipherpki']) && 
483
				$settings['cipherpki'] != "none") 
484
                        	$openvpn_conf .= $key['directive'] . " " . $base_file . $settings['cipherpki'] . 
485
							"/".$key['field']."\n";
486
			else if ($settings['auth_method'] == 'pki' && isset($settings['cipherpki']) && 
487
				$settings['cipherpki'] != "none") 
488
                        	$openvpn_conf .= $key['directive'] . " " . $base_file . $settings['cipherpki'] . 
489
							"/".$key['field']."\n";
490
                } else {
491
                        $filename = $g['varetc_path']."/openvpn_{$mode}{$id}." . $key['field'];
492
                        file_put_contents($filename, base64_decode($settings[$key['field']]));
493
                        chown($filename, 'nobody');
494
                        chgrp($filename, 'nobody');
495
                        $openvpn_conf .= $key['directive'] . " $filename \n";
496
                }
497
        }
498

    
499
	if ($settings['use_lzo']) $openvpn_conf .= "comp-lzo\n";
500

    
501
	if ($settings['passtos']) $openvpn_conf .= "passtos\n";
502
	
503
	if ($settings['infiniteresolvretry']) $openvpn_conf .= "resolv-retry infinite\n";
504
	
505
	if ($settings['dynamic_ip']) {
506
		$openvpn_conf .= "persist-remote-ip\n";
507
		$openvpn_conf .= "float\n";
508
	}
509

    
510
	if (!empty($settings['custom_options'])) {
511
		$options = explode(';', $settings['custom_options']);
512
		if (is_array($options)) {
513
			foreach ($options as $option)
514
				$openvpn_conf .= "$option\n";
515
		}
516
		else {
517
			$openvpn_conf .= "{$settings['custom_options']}\n";
518
		}
519
	}
520

    
521
	file_put_contents($g['varetc_path'] . "/openvpn_{$mode}{$id}.conf", $openvpn_conf);
522
}
523

    
524

    
525
function openvpn_resync_csc($id) {
526
	global $g, $config;
527

    
528
	$settings = $config['installedpackages']['openvpncsc']['config'][$id];
529

    
530
	if ($settings['disable'] == 'on') {
531
		$filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
532
		unlink_if_exists($filename);
533
		return;
534
	}
535
	
536
	$conf = '';
537
	if ($settings['block'] == 'on') $conf .= "disable\n";
538
	if ($settings['push_reset'] == 'on') $conf .= "push-reset\n";
539
	if (!empty($settings['ifconfig_push'])) {
540
		list($ip, $mask) = explode('/', $settings['ifconfig_push']);
541
		$baselong = ip2long($ip) & gen_subnet_mask_long($mask);
542
		$conf .= 'ifconfig-push ' . long2ip($baselong + 1) . ' ' . long2ip($baselong + 2) . "\n";
543
	}
544

    
545
// DHCP-Options
546
	  if (!empty($settings['dhcp_domainname'])) $conf .= "push \"dhcp-option DOMAIN {$settings['dhcp_domainname']}\"\n";
547

    
548
    if (!empty($settings['dhcp_dns'])) {
549
	   	$servers = explode(';', $settings['dhcp_dns']);
550
   	  if (is_array($servers)) {
551
			 foreach ($servers as $server) $conf .= "push \"dhcp-option DNS {$server}\"\n";
552
  	  }
553
		  else {
554
			$conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
555
		  }
556
    }
557

    
558
    if (!empty($settings['dhcp_wins'])) {
559
	   	$servers = explode(';', $settings['dhcp_wins']);
560
   	  if (is_array($servers)) {
561
			 foreach ($servers as $server) $conf .= "push \"dhcp-option WINS {$server}\"\n";
562
  	  }
563
		  else {
564
			$conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
565
		  }
566
    }
567

    
568
    if (!empty($settings['dhcp_nbdd'])) {
569
	   	$servers = explode(';', $settings['dhcp_nbdd']);
570
   	  if (is_array($servers)) {
571
			 foreach ($servers as $server) $conf .= "push \"dhcp-option NBDD {$server}\"\n";
572
  	  }
573
		  else {
574
			$conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
575
		  }
576
    }
577

    
578
    if (!empty($settings['dhcp_ntp'])) {
579
	   	$servers = explode(';', $settings['dhcp_ntp']);
580
   	  if (is_array($servers)) {
581
			 foreach ($servers as $server) $conf .= "push \"dhcp-option NTP {$server}\"\n";
582
  	  }
583
		  else {
584
			$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
585
		  }
586
    }
587

    
588
  	if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
589
    if (!empty($settings['dhcp_nbtscope'])) $conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
590
   	if ($settings['dhcp_nbtdisable']) $conf .= "push \"dhcp-option DISABLE-NBT\"\n";
591
    if ($settings['gwredir']) $conf .= "push \"redirect-gateway def1\"\n";
592

    
593
	if (!empty($settings['custom_options'])) {
594
		$options = explode(';', $settings['custom_options']);
595
		if (is_array($options)) {
596
			foreach ($options as $option)
597
				$conf .= "$option\n";
598
		}
599
		else {
600
			$conf .= "{$settings['custom_options']}\n";
601
		}
602
	}
603

    
604
	$filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
605
	file_put_contents($filename, $conf);
606
	chown($filename, 'nobody');
607
	chgrp($filename, 'nogroup');
608

    
609
}
610

    
611

    
612
function openvpn_restart($mode, $id) {
613
	global $g, $config;
614

    
615
	$pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
616
	killbypid($pidfile);
617
	sleep(2);
618

    
619
	$settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
620
	if ($settings['disable']) return;
621

    
622
	$configfile = $g['varetc_path'] . "/openvpn_{$mode}{$id}.conf";
623
	mwexec_bg("nohup openvpn --config $configfile");// --dev-type tun --dev-node /dev/tun{$id}");
624
	touch("{$g['tmp_path']}/filter_dirty");
625
}
626

    
627
//Make ciphers ready for openvpn
628
function openvpn_restore_all_ciphers() {
629
        global $config, $g;
630

    
631
        $ovpncapath = $g['varetc_path']."/openvpn/certificates";
632

    
633
        if (is_array($config['openvpn']['keys'])) {
634
                if (!is_dir($g['varetc_path']."/openvpn"))
635
                        safe_mkdir($g['varetc_path']."/openvpn");
636
                if (!is_dir($ovpncapath))
637
                        safe_mkdir($ovpncapath);
638

    
639
                /* XXX: hardcoded path; worth making it a global?! */
640
                mwexec("cp -r /usr/local/share/openvpn/certificates ".$g['varetc_path']."/openvpn/");
641
                if (!is_dir($ovpncapath)) {
642
                        log_error("Failed to create environment for creating certificates. ");
643
                } else {
644

    
645
                        foreach ($config['openvpn']['keys'] as $caname => $ciphers) {
646
                                if (!is_dir("$ovpncapath/$caname"))
647
                                        safe_mkdir("$ovpncapath/$caname");
648

    
649
                                $cfg = "";
650
                                /* NOTE: vars; Do we need them restored?! */
651
                                $cfg .= "setenv KEY_SIZE " .$ciphers['keysize'] ."\n";
652
                                $cfg .= "setenv KEY_EXPIRE ".$ciphers['keyexpire'] ."\n";
653
                                $cfg .= "setenv CA_EXPIRE " .$ciphers['caexpire'] . "\n";
654
                                $cfg .= "setenv KEY_COUNTRY " .$ciphers['keycountry'] ."\n";
655
                                $cfg .= "setenv KEY_RPOVINCE " .$ciphers['keyprovince'] . "\n";
656
                                $cfg .= "setenv KEY_CITY " .$ciphers['keycity'] . "\n";
657
                                $cfg .= "setenv KEY_ORG " .$ciphers['keyorg'] . "\n";
658
                                $cfg .= "setenv KEY_EMAIL " .$ciphers['keyemail'] . "\n";
659
                                file_put_contents("$ovpncapath/$caname/vars", $cfg);
660
                                /* put ciphers back in their files */
661
                                foreach ($ciphers as $filename => $value) {
662
                                        file_put_contents("$ovpncapath/$caname/$filename", $value);
663
                                }
664
                        }
665
                }
666
        }
667
}
668

    
669
// Resync the configuration and restart the VPN
670
function openvpn_resync($mode, $id) {
671
	openvpn_reconfigure($mode, $id);
672
	openvpn_restart($mode, $id);
673
}
674

    
675
function openvpn_create_cscdir() {
676
	global $g;
677

    
678
	$csc_dir = "{$g['varetc_path']}/openvpn_csc";
679
	if (is_dir($csc_dir))
680
		rmdir_recursive($csc_dir);
681
	make_dirs($csc_dir);
682
	chown($csc_dir, 'nobody');
683
	chgrp($csc_dir, 'nobody');
684
}
685

    
686
// Resync and restart all VPNs
687
function openvpn_resync_all() {
688
	global $config;
689
	$ovpncapath = $g['varetc_path']."/openvpn/certificates";
690

    
691
 	openvpn_restore_all_ciphers();
692

    
693
	foreach (array('server', 'client') as $mode) {
694
		if ($config['installedpackages']["openvpn$mode"]) {
695
			if (is_array($config['installedpackages']["openvpn$mode"]['config'])) {
696
				foreach ($config['installedpackages']["openvpn$mode"]['config'] as $id => $settings)
697
					openvpn_resync($mode, $id);
698
			}
699
		}
700
	}
701

    
702
	openvpn_create_cscdir();
703
	if ($config['installedpackages']['openvpncsc']) {
704
		if (is_array($config['installedpackages']['openvpncsc']['config'])) {
705
			foreach ($config['installedpackages']['openvpncsc']['config'] as $id => $csc)
706
				openvpn_resync_csc($id);
707
		}
708
	}
709
	
710
	/* give speedy machines time to settle */
711
	sleep(5);
712

    
713
	/* reload the filter policy */
714
	filter_configure();
715

    
716
}
717

    
718
function openvpn_print_javascript($mode) {
719
	$javascript = <<<EOD
720
<script language="JavaScript">
721
//<!--
722
function onAuthMethodChanged() {
723
	var method = document.iform.auth_method;
724
	var endis = (method.options[method.selectedIndex].value == 'shared_key');
725

    
726
	if ('$mode' == 'server') {
727
	document.iform.nopool.disabled = endis;
728
	document.iform.local_network.disabled = endis;
729
	document.iform.client2client.disabled = endis;
730
	document.iform.maxclients.disabled = endis;
731
	document.iform.cipher.disabled = !endis;
732
	document.iform.cipherpki.disabled = endis;
733
	}
734
	else { // Client mode
735
		document.iform.remote_network.disabled = !endis;;
736
 	        document.iform['shared.key'].disabled = !endis;
737
    	   	document.iform['ca.crt'].disabled = endis;
738
        	document.iform["{$mode}.crt"].disabled = endis;
739
        	document.iform["{$mode}.key"].disabled = endis;
740
        	document.iform.tls.disabled = endis;
741
	}
742
}
743
//-->
744
</script>
745

    
746
EOD;
747
	print($javascript);
748
}
749

    
750

    
751
function openvpn_print_javascript2() {
752
	$javascript = <<<EOD
753
<script language="JavaScript">
754
//<!--
755
	onAuthMethodChanged();
756
//-->
757
</script>
758

    
759
EOD;
760
	print($javascript);
761
}
762
?>
(14-14/29)