Project

General

Profile

Download (26.1 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 => $none) {
62
						$option_array[] = array('value' => $cipher, 'name' => $cipher);
63
                       			}
64
                		}
65
        		}
66
		}
67
	}
68
}
69

    
70

    
71
function openvpn_validate_port($value, $name) {
72
	$value = trim($value);
73
	if (!empty($value) && !(is_numeric($value) && ($value > 0) && ($value < 65535)))
74
		return "The field '$name' must contain a valid port, ranging from 0 to 65535.";
75
	return false;
76
}
77

    
78

    
79
function openvpn_validate_cidr($value, $name) {
80
	$value = trim($value);
81
	if (!empty($value)) {
82
		list($ip, $mask) = explode('/', $value);
83
		if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
84
			return "The field '$name' must contain a valid CIDR range.";
85
	}
86
	return false;
87
}
88

    
89

    
90
// Do the input validation
91
function openvpn_validate_input($mode, $post, $input_errors) {
92
	$Mode = ucfirst($mode);
93

    
94
	if ($mode == 'server') {
95
		if ($result = openvpn_validate_port($post['local_port'], 'Local port'))
96
			$input_errors[] = $result;
97

    
98
		if ($result = openvpn_validate_cidr($post['addresspool'], 'Address pool'))
99
			$input_errors[] = $result;
100

    
101
		if ($result = openvpn_validate_cidr($post['local_network'], 'Local network'))
102
			$input_errors[] = $result;
103

    
104
	if (!empty($post['dhcp_dns'])) {
105
    $servers = explode(';', $post['dhcp_dns']);
106
      foreach ($servers as $server) if (!is_ipaddr($server))
107
        {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
108
        break;}}
109
	if (!empty($post['dhcp_wins'])) {
110
    $servers = explode(';', $post['dhcp_wins']);
111
      foreach ($servers as $server) if (!is_ipaddr($server))
112
        {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
113
        break;}}
114
	if (!empty($post['dhcp_nbdd'])) {
115
    $servers = explode(';', $post['dhcp_nbdd']);
116
      foreach ($servers as $server) if (!is_ipaddr($server))
117
        {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
118
        break;}}
119
	if (!empty($post['dhcp_ntp'])) {
120
    $servers = explode(';', $post['dhcp_ntp']);
121
      foreach ($servers as $server) if (!is_ipaddr($server))
122
        {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
123
        break;}}
124
	if (isset($post['maxclients']) && $post['maxclients'] != "") {
125
		if (!is_numeric($post['maxclients']))
126
			$input_errors[] = 'The field \'Maximum clients\' must be numeric.';
127
		}
128

    
129
	}
130

    
131
	else { // Client mode
132
		if ($result = openvpn_validate_port($post['serverport'], 'Server port'))
133
			$input_errors[] = $result;
134

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

    
139
		if ($result = openvpn_validate_cidr($post['interface_ip'], 'Interface IP'))
140
			$input_errors[] = $result;
141

    
142
		if ($post['auth_method'] == 'shared_key') {
143
			if (empty($post['interface_ip']))
144
				$input_errors[] = 'The field \'Interface IP\' is required.';
145
		}
146
		if (isset($post['proxy_hostname']) && $post['proxy_hostname'] != "") {
147
			if (!is_domain($post['proxy_hostname']) || is_ipaddr($post['proxy_hostname']))
148
				$input_errors[] = 'The field \'Proxy Host\' must contain a valid IP address or domain name.';
149
			if (!is_port($post['proxy_port']))
150
				$input_errors[] = 'The field \'Proxy port\' must contain a valid port number.';
151
			if ($post['protocol'] != "TCP")
152
				$input_errors[] = 'The protocol must be TCP to use a HTTP proxy server.';
153
		}
154
		if (isset($post['use_shaper']) && $post['use_shaper'] != "") {
155
			if (!is_numeric($post['use_shaper']))
156
				$input_errors[] = 'The field \'Limit outgoing bandwidth\' must be numeric.';
157
		}
158

    
159
	}
160

    
161
	if ($result = openvpn_validate_cidr($post['remote_network'], 'Remote network'))
162
		$input_errors[] = $result;
163

    
164
/* This are no more needed comment them from now and remove later */
165
/*
166
	if ($_POST['auth_method'] == 'shared_key') {
167
		$reqfields[] = 'shared_key';
168
		$reqfieldsn[] = 'Shared key';
169
	}
170
	else {
171
		$req = explode(' ', "ca_cert {$mode}_cert {$mode}_key");
172
		$reqn = array(	'CA certificate',
173
				ucfirst($mode) . ' certificate',
174
				ucfirst($mode) . ' key');
175
		$reqfields = array_merge($reqfields, $req);
176
		$reqfieldsn = array_merge($reqfieldsn, $reqn);
177
		if ($mode == 'server') {
178
			$reqfields[] = 'dh_params';
179
			$reqfieldsn[] = 'DH parameters';
180
		}
181
	}
182
	do_input_validation($post, $reqfields, $reqfieldsn, &$input_errors);
183
*/
184
if ($mode != "server") {
185
	$value = trim($post['shared_key']);
186
	$items = array();
187

    
188
	if ($_POST['auth_method'] == 'shared_key') {
189
		$items[] = array(	'field' => 'shared.key',
190
					'string' => 'OpenVPN Static key V1',
191
					'name' => 'Shared key');
192
	}
193
	else {
194
		$items[] = array(	'field' => 'ca.crt',
195
					'string' => 'CERTIFICATE',
196
					'name' => 'CA certificate');
197
		$items[] = array(	'field' => "{$mode}.crt",
198
					'string' => 'CERTIFICATE',
199
					'name' => "$Mode certificate");
200
		$items[] = array(	'field' => "{$mode}.key",
201
					'string' => 'RSA PRIVATE KEY',
202
					'name' => "$Mode key");
203
	  $items[] = array(	'field' => 'tls',
204
		      'string' => 'OpenVPN Static key V1',
205
		      'name' => 'TLS');
206
		if ($mode == 'server') {
207
			$items[] = array(	'field' => 'dh_param.dhs',
208
						'string' => 'DH PARAMETERS',
209
						'name' => 'DH parameters');
210
			$items[] = array(	'field' => 'crlcrl',
211
						'string' => 'X509 CRL',
212
						'name' => 'CRL');
213
		}
214
	}
215
	foreach ($items as $item) {
216
		$value = trim($_POST[$item['field']]);
217
		$string = $item['string'];
218
		if ($value && (!strstr($value, "-----BEGIN {$string}-----") || !strstr($value, "-----END {$string}-----")))
219
			$input_errors[] = "The field '{$item['name']}' does not appear to be valid";
220
	}
221
}
222
}
223

    
224

    
225
function openvpn_validate_input_csc($post, $input_errors) {
226
	if ($result = openvpn_validate_cidr($post['ifconfig_push'], 'Interface IP'))
227
		$input_errors[] = $result;
228

    
229
	if ($post['push_reset'] != 'on') {
230
    if (!empty($post['dhcp_domainname']))
231
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
232
    elseif (!empty($post['dhcp_dns']))
233
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
234
    elseif (!empty($post['dhcp_wins']))
235
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
236
    elseif (!empty($post['dhcp_nbdd']))
237
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
238
    elseif (!empty($post['dhcp_ntp']))
239
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
240
    elseif ($post['dhcp_nbttype'])
241
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
242
    elseif (!empty($post['dhcp_nbtscope']))
243
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
244
    elseif ($post['dhcp_nbtdisable'])
245
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
246

    
247
  }
248
  else {
249

    
250
	if (!empty($post['dhcp_dns'])) {
251
    $servers = explode(';', $post['dhcp_dns']);
252
      foreach ($servers as $server) if (!is_ipaddr($server))
253
        {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
254
        break;}}
255
	if (!empty($post['dhcp_wins'])) {
256
    $servers = explode(';', $post['dhcp_wins']);
257
      foreach ($servers as $server) if (!is_ipaddr($server))
258
        {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
259
        break;}}
260
	if (!empty($post['dhcp_nbdd'])) {
261
    $servers = explode(';', $post['dhcp_nbdd']);
262
      foreach ($servers as $server) if (!is_ipaddr($server))
263
        {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
264
        break;}}
265
	if (!empty($post['dhcp_ntp'])) {
266
    $servers = explode(';', $post['dhcp_ntp']);
267
      foreach ($servers as $server) if (!is_ipaddr($server))
268
        {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
269
        break;}}
270

    
271
}}
272

    
273
// Rewrite the settings
274
function openvpn_reconfigure($mode, $id) {
275
	global $g, $config;
276

    
277
	$settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
278
	if ($settings['disable']) return;
279

    
280
	$lport = 1194 + $id;
281

    
282
	mwexec("/sbin/ifconfig tun{$id} create");
283
	mwexec("/sbin/ifconfig tun{$id} name openvpn{$id}");
284
	mwexec("/sbin/ifconfig openvpn{$id} group openvpn");
285

    
286
        $pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
287
        $proto = ($settings['protocol'] == 'UDP' ? 'udp' : "tcp-{$mode}");
288
        $cipher = $settings['crypto'];
289
	$openvpn_conf = "dev openvpn{$id}\n";
290
        $openvpn_conf .= <<<EOD
291
writepid $pidfile
292
#user nobody
293
#group nobody
294
daemon
295
keepalive 10 60
296
ping-timer-rem
297
persist-tun
298
persist-key
299
proto $proto
300
cipher $cipher
301
up /etc/rc.filter_configure
302
down /etc/rc.filter_configure
303

    
304
EOD;
305

    
306
	// Mode-specific stuff
307
	if ($mode == 'server') {
308
		list($ip, $mask) = explode('/', $settings['addresspool']);
309
		$mask = gen_subnet_mask($mask);
310

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

    
315
			$baselong = ip2long($ip) & ip2long($mask);
316
			$ip1 = long2ip($baselong + 1);
317
			$ip2 = long2ip($baselong + 2);
318
			$openvpn_conf .= "ifconfig $ip1 $ip2\n";
319
		}
320
		// Using a PKI
321
		else if ($settings['auth_method'] == 'pki') {
322
			if ($settings['client2client']) $openvpn_conf .= "client-to-client\n";
323
			$openvpn_conf .= "server $ip $mask\n";
324
			$csc_dir = "{$g['varetc_path']}/openvpn_csc";
325
			$openvpn_conf .= "client-config-dir $csc_dir\n";
326
		}
327

    
328
		// We can push routes
329
		if (!empty($settings['local_network'])) {
330
			list($ip, $mask) = explode('/', $settings['local_network']);
331
			$mask = gen_subnet_mask($mask);
332
			$openvpn_conf .= "push \"route $ip $mask\"\n";
333
		}
334

    
335
        if ($settings['bind_to_iface'] == 'on') {
336
            $iface = $settings['interface'];
337
            $iface = convert_friendly_interface_to_real_interface_name($iface);
338
            $line = trim(shell_exec("ifconfig $iface | grep inet | grep -v inet6"));
339
            list($dummy, $ip, $dummy2, $dummy3) = explode(' ', $line);
340

    
341
            $openvpn_conf .= "local {$ip}\n";
342
        }
343

    
344
		// The port we'll listen at
345
		$openvpn_conf .= "lport {$settings['local_port']}\n";
346

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

    
350
    if (!empty($settings['dhcp_dns'])) {
351
	   	$servers = explode(';', $settings['dhcp_dns']);
352
   	  if (is_array($servers)) {
353
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option DNS {$server}\"\n";
354
  	  }
355
		  else {
356
			$openvpn_conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
357
		  }
358
    }
359

    
360
    if (!empty($settings['dhcp_wins'])) {
361
	   	$servers = explode(';', $settings['dhcp_wins']);
362
   	  if (is_array($servers)) {
363
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option WINS {$server}\"\n";
364
  	  }
365
		  else {
366
			$openvpn_conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
367
		  }
368
    }
369

    
370
    if (!empty($settings['dhcp_nbdd'])) {
371
	   	$servers = explode(';', $settings['dhcp_nbdd']);
372
   	  if (is_array($servers)) {
373
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NBDD {$server}\"\n";
374
  	  }
375
		  else {
376
			$openvpn_conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
377
		  }
378
    }
379

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

    
390
  	if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $openvpn_conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
391
    if (!empty($settings['dhcp_nbtscope'])) $openvpn_conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
392
   	if ($settings['dhcp_nbtdisable']) $openvpn_conf .= "push \"dhcp-option DISABLE-NBT\"\n";
393

    
394
    if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_server{$id}.tls 0\n";
395
		if (!empty($settings['maxclients'])) $openvpn_conf .= "max-clients {$settings['maxclients']}\n";
396
		if ($settings['gwredir']) $openvpn_conf .= "push \"redirect-gateway def1\"\n";
397
		if ($settings['keepalive']) $openvpn_conf .= "keepalive 12 120\n";
398
			}
399

    
400
	else { // $mode == client
401
		// The remote server
402
		$openvpn_conf .= "remote {$settings['serveraddr']} {$settings['serverport']}\n";
403

    
404
		if ($settings['auth_method'] == 'pki') $openvpn_conf .= "client\n";
405
		if ($settings['use_dynamicport']) $openvpn_conf .= "nobind\n";
406
			else
407
			// The port we'll listen at
408
			$openvpn_conf .= "lport {$lport}\n";
409

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

    
412
		if (!empty($settings['interface_ip'])) {
413
			// Configure the IPs according to the address pool
414
			list($ip, $mask) = explode('/', $settings['interface_ip']);
415
			$mask = gen_subnet_mask($mask);
416
			$baselong = ip2long($ip) & ip2long($mask);
417
			$ip1 = long2ip($baselong + 1);
418
			$ip2 = long2ip($baselong + 2);
419
			$openvpn_conf .= "ifconfig $ip2 $ip1\n";
420
		}
421
		if (isset($settings['proxy_hostname']) && $settings['proxy_hostname'] != "") {
422
			/* ;http-proxy-retry # retry on connection failures */
423
			$openvpn_conf .= "http-proxy {$settings['proxy_hostname']} {$settings['proxy_port']}\n";
424
		}
425

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

    
428
	}
429

    
430
	// Add the routes if they're set
431
	if (!empty($settings['remote_network'])) {
432
		list($ip, $mask) = explode('/', $settings['remote_network']);
433
		$mask = gen_subnet_mask($mask);
434
		$openvpn_conf .= "route $ip $mask\n";
435
	}
436

    
437
        // Write the settings for the keys
438
        // Set the keys up
439
        $base_file = $g['varetc_path'] . "/openvpn/certificates/";
440
        $keys = array();
441
        if ($settings['auth_method'] == 'shared_key')
442
                $keys[] = array('field' => 'shared_key', 'ext'  => 'secret', 'directive' => 'secret');
443
        else {
444
                $keys[] = array('field' => 'ca.crt', 'directive' => 'ca');
445
                $keys[] = array('field' => "{$mode}.crt", 'directive' => 'cert');
446
                $keys[] = array('field' => "{$mode}.key", 'directive' => 'key');
447
                if ($mode == 'server')
448
                        $keys[] = array('field' => 'dh_params.dh', 'directive' => 'dh');
449
                if ($settings['crl'])
450
                        $keys[] = array('field' => 'crl.crl', 'directive' => 'crl-verify');
451
        }
452

    
453
        foreach ($keys as $key) {
454
                if ($mode == "server" && $settings['cipher'] != "none") {
455
                        $openvpn_conf .= $key['directive'] . " " . $base_file . $settings['cipher'] . "/".$key['field'] . "\n";
456
                } else {
457
                        $filename = "$base_file/openvpn_{$mode}{$id}." . $key['field'];
458
                        file_put_contents($filename, base64_decode($settings[$key['field']]));
459
                        chown($filename, 'nobody');
460
                        chgrp($filename, 'nobody');
461
                        $openvpn_conf .= $key['directive'] . " $filename \n";
462
                }
463
        }
464

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

    
467
	if ($settings['passtos']) $openvpn_conf .= "passtos\n";
468
	
469
	if ($settings['infiniteresolvretry']) $openvpn_conf .= "resolv-retry infinite\n";
470
	
471
	if ($settings['dynamic_ip']) {
472
		$openvpn_conf .= "persist-remote-ip\n";
473
		$openvpn_conf .= "float\n";
474
	}
475

    
476
	if (!empty($settings['custom_options'])) {
477
		$options = explode(';', $settings['custom_options']);
478
		if (is_array($options)) {
479
			foreach ($options as $option)
480
				$openvpn_conf .= "$option\n";
481
		}
482
		else {
483
			$openvpn_conf .= "{$settings['custom_options']}\n";
484
		}
485
	}
486

    
487
	file_put_contents($g['varetc_path'] . "/openvpn_{$mode}{$id}.conf", $openvpn_conf);
488
}
489

    
490

    
491
function openvpn_resync_csc($id) {
492
	global $g, $config;
493

    
494
	$settings = $config['installedpackages']['openvpncsc']['config'][$id];
495

    
496
	if ($settings['disable'] == 'on') {
497
		$filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
498
		unlink_if_exists($filename);
499
		return;
500
	}
501
	
502
	$conf = '';
503
	if ($settings['block'] == 'on') $conf .= "disable\n";
504
	if ($settings['push_reset'] == 'on') $conf .= "push-reset\n";
505
	if (!empty($settings['ifconfig_push'])) {
506
		list($ip, $mask) = explode('/', $settings['ifconfig_push']);
507
		$baselong = ip2long($ip) & gen_subnet_mask_long($mask);
508
		$conf .= 'ifconfig-push ' . long2ip($baselong + 1) . ' ' . long2ip($baselong + 2) . "\n";
509
	}
510

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

    
514
    if (!empty($settings['dhcp_dns'])) {
515
	   	$servers = explode(';', $settings['dhcp_dns']);
516
   	  if (is_array($servers)) {
517
			 foreach ($servers as $server) $conf .= "push \"dhcp-option DNS {$server}\"\n";
518
  	  }
519
		  else {
520
			$conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
521
		  }
522
    }
523

    
524
    if (!empty($settings['dhcp_wins'])) {
525
	   	$servers = explode(';', $settings['dhcp_wins']);
526
   	  if (is_array($servers)) {
527
			 foreach ($servers as $server) $conf .= "push \"dhcp-option WINS {$server}\"\n";
528
  	  }
529
		  else {
530
			$conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
531
		  }
532
    }
533

    
534
    if (!empty($settings['dhcp_nbdd'])) {
535
	   	$servers = explode(';', $settings['dhcp_nbdd']);
536
   	  if (is_array($servers)) {
537
			 foreach ($servers as $server) $conf .= "push \"dhcp-option NBDD {$server}\"\n";
538
  	  }
539
		  else {
540
			$conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
541
		  }
542
    }
543

    
544
    if (!empty($settings['dhcp_ntp'])) {
545
	   	$servers = explode(';', $settings['dhcp_ntp']);
546
   	  if (is_array($servers)) {
547
			 foreach ($servers as $server) $conf .= "push \"dhcp-option NTP {$server}\"\n";
548
  	  }
549
		  else {
550
			$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
551
		  }
552
    }
553

    
554
  	if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
555
    if (!empty($settings['dhcp_nbtscope'])) $conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
556
   	if ($settings['dhcp_nbtdisable']) $conf .= "push \"dhcp-option DISABLE-NBT\"\n";
557
    if ($settings['gwredir']) $conf .= "push \"redirect-gateway def1\"\n";
558
    if ($settings['keepalive']) $conf .= "keepalive 12 120\n";
559

    
560
	if (!empty($settings['custom_options'])) {
561
		$options = explode(';', $settings['custom_options']);
562
		if (is_array($options)) {
563
			foreach ($options as $option)
564
				$conf .= "$option\n";
565
		}
566
		else {
567
			$conf .= "{$settings['custom_options']}\n";
568
		}
569
	}
570

    
571
	$filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
572
	file_put_contents($filename, $conf);
573
	chown($filename, 'nobody');
574
	chgrp($filename, 'nogroup');
575

    
576
}
577

    
578

    
579
function openvpn_restart($mode, $id) {
580
	global $g, $config;
581

    
582
	$pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
583
	killbypid($pidfile);
584
	sleep(2);
585

    
586
	$settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
587
	if ($settings['disable']) return;
588

    
589
	$configfile = $g['varetc_path'] . "/openvpn_{$mode}{$id}.conf";
590
	mwexec_bg("nohup openvpn --config $configfile");
591
	touch("{$g['tmp_path']}/filter_dirty");
592
}
593

    
594
//Make ciphers ready for openvpn
595
function openvpn_restore_all_ciphers() {
596
        global $config, $g;
597

    
598
        $ovpncapath = $g['varetc_path']."/openvpn/certificates";
599

    
600
        if (is_array($config['openvpn']['keys'])) {
601
                if (!is_dir($g['varetc_path']."/openvpn"))
602
                        safe_mkdir($g['varetc_path']."/openvpn");
603
                if (!is_dir($ovpncapath))
604
                        safe_mkdir($ovpncapath);
605

    
606
                /* XXX: hardcoded path; worth making it a global?! */
607
                mwexec("cp -r /usr/local/share/openvpn/certificates ".$g['varetc_path']."/openvpn/");
608
                if (!is_dir($ovpncapath)) {
609
                        log_error("Failed to create environment for creating certificates. ");
610
                } else {
611

    
612
                        foreach ($config['openvpn']['keys'] as $caname => $ciphers) {
613
                                if (!is_dir("$ovpncapath/$caname"))
614
                                        safe_mkdir("$ovpncapath/$caname");
615

    
616
                                $cfg = "";
617
                                /* NOTE: vars; Do we need them restored?! */
618
                                $cfg .= "setenv KEY_SIZE " .$ciphers['keysize'] ."\n";
619
                                $cfg .= "setenv KEY_EXPIRE ".$ciphers['keyexpire'] ."\n";
620
                                $cfg .= "setenv CA_EXPIRE " .$ciphers['caexpire'] . "\n";
621
                                $cfg .= "setenv KEY_COUNTRY " .$ciphers['keycountry'] ."\n";
622
                                $cfg .= "setenv KEY_RPOVINCE " .$ciphers['keyprovince'] . "\n";
623
                                $cfg .= "setenv KEY_CITY " .$ciphers['keycity'] . "\n";
624
                                $cfg .= "setenv KEY_ORG " .$ciphers['keyorg'] . "\n";
625
                                $cfg .= "setenv KEY_EMAIL " .$ciphers['keyemail'] . "\n";
626
                                file_put_contents("$ovpncapath/$caname/vars", $cfg);
627
                                /* put ciphers back in their files */
628
                                foreach ($ciphers as $filename => $value) {
629
                                        file_put_contents("$ovpncapath/$caname/$filename", $value);
630
                                }
631
                        }
632
                }
633
        }
634
}
635

    
636
// Resync the configuration and restart the VPN
637
function openvpn_resync($mode, $id) {
638
	openvpn_reconfigure($mode, $id);
639
	openvpn_restart($mode, $id);
640
}
641

    
642
function openvpn_create_cscdir() {
643
	global $g;
644

    
645
	$csc_dir = "{$g['varetc_path']}/openvpn_csc";
646
	if (is_dir($csc_dir))
647
		rmdir_recursive($csc_dir);
648
	make_dirs($csc_dir);
649
	chown($csc_dir, 'nobody');
650
	chgrp($csc_dir, 'nobody');
651
}
652

    
653
// Resync and restart all VPNs
654
function openvpn_resync_all() {
655
	global $config;
656
	$ovpncapath = $g['varetc_path']."/openvpn/certificates";
657

    
658
 	openvpn_restore_all_ciphers();
659

    
660
	foreach (array('server', 'client') as $mode) {
661
		if ($config['installedpackages']["openvpn$mode"]) {
662
			if (is_array($config['installedpackages']["openvpn$mode"]['config'])) {
663
				foreach ($config['installedpackages']["openvpn$mode"]['config'] as $id => $settings)
664
					openvpn_resync($mode, $id);
665
			}
666
		}
667
	}
668

    
669
	openvpn_create_cscdir();
670
	if ($config['installedpackages']['openvpncsc']) {
671
		if (is_array($config['installedpackages']['openvpncsc']['config'])) {
672
			foreach ($config['installedpackages']['openvpncsc']['config'] as $id => $csc)
673
				openvpn_resync_csc($id);
674
		}
675
	}
676
	
677
	/* give speedy machines time to settle */
678
	sleep(5);
679

    
680
	/* reload the filter policy */
681
	filter_configure();
682

    
683
}
684

    
685
function openvpn_print_javascript($mode) {
686
	$javascript = <<<EOD
687
<script language="JavaScript">
688
<!--
689
function onAuthMethodChanged() {
690
	var method = document.iform.auth_method;
691
	var endis = (method.options[method.selectedIndex].value == 'shared_key');
692

    
693
	document.iform.shared.key.disabled = !endis;
694
	document.iform.ca.crt.disabled = endis;
695
	document.iform.{$mode}.crt.disabled = endis;
696
	document.iform.{$mode}.key.disabled = endis;
697
    document.iform.tls.disabled = endis;
698

    
699
EOD;
700
	if ($mode == 'server') {
701
		$javascript .= <<<EOD
702
	document.iform.nopool.disabled = endis;
703
	document.iform.local_network.disabled = endis;
704
	document.iform.client2client.disabled = endis;
705
	document.iform.maxclients.disabled = endis;
706

    
707
EOD;
708
	}
709

    
710
	else { // Client mode
711
		$javascript .= "\tdocument.iform.remote_network.disabled = !endis;\n";
712
	}
713

    
714
	$javascript .= <<<EOD
715
}
716
//-->
717
</script>
718

    
719
EOD;
720
	print($javascript);
721
}
722

    
723

    
724
function openvpn_print_javascript2() {
725
	$javascript = <<<EOD
726
<script language="JavaScript">
727
<!--
728
	onAuthMethodChanged();
729
//-->
730
</script>
731

    
732
EOD;
733
	print($javascript);
734
}
735
?>
(14-14/29)