Project

General

Profile

Download (22.6 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 b1ad443d Scott Ullrich
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 8dc3ef67 Scott Ullrich
require_once('config.inc');
38 36df0acc Scott Ullrich
require_once('pfsense-utils.inc');
39 8dc3ef67 Scott Ullrich
require_once('util.inc');
40
41 add2e3f7 Scott Ullrich
// Return the list of ciphers OpenVPN supports
42
function openvpn_get_ciphers($pkg) {
43 8dc3ef67 Scott Ullrich
		foreach ($pkg['fields']['field'] as $i => $field) {
44
			if ($field['fieldname'] == 'crypto') break;
45
		}
46
		$option_array = &$pkg['fields']['field'][$i]['options']['option'];
47
		$ciphers_out = shell_exec('openvpn --show-ciphers | grep "default key" | awk \'{print $1, "(" $2 "-" $3 ")";}\'');
48
		$ciphers = explode("\n", trim($ciphers_out));
49 add2e3f7 Scott Ullrich
		sort($ciphers);
50 8dc3ef67 Scott Ullrich
		foreach ($ciphers as $cipher) {
51
			$value = explode(' ', $cipher);
52
			$value = $value[0];
53
			$option_array[] = array('value' => $value, 'name' => $cipher);
54
		}
55
}
56
57
58
function openvpn_validate_port($value, $name) {
59
	$value = trim($value);
60
	if (!empty($value) && !(is_numeric($value) && ($value > 0) && ($value < 65535)))
61
		return "The field '$name' must contain a valid port, ranging from 0 to 65535.";
62
	return false;
63
}
64
65
66
function openvpn_validate_cidr($value, $name) {
67
	$value = trim($value);
68
	if (!empty($value)) {
69
		list($ip, $mask) = explode('/', $value);
70
		if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
71
			return "The field '$name' must contain a valid CIDR range.";
72
	}
73
	return false;
74 afb07cf1 Scott Ullrich
}
75
76
77 add2e3f7 Scott Ullrich
// Do the input validation
78
function openvpn_validate_input($mode, $post, $input_errors) {
79
	$Mode = ucfirst($mode);
80
81 8dc3ef67 Scott Ullrich
	if ($mode == 'server') {
82
		if ($result = openvpn_validate_port($post['local_port'], 'Local port'))
83
			$input_errors[] = $result;
84
85
		if ($result = openvpn_validate_cidr($post['addresspool'], 'Address pool'))
86
			$input_errors[] = $result;
87
88
		if ($result = openvpn_validate_cidr($post['local_network'], 'Local network'))
89
			$input_errors[] = $result;
90 f9927473 Scott Ullrich
91 7528fc09 Scott Ullrich
	if (!empty($post['dhcp_dns'])) {
92 f9927473 Scott Ullrich
    $servers = explode(';', $post['dhcp_dns']);
93 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
94 f9927473 Scott Ullrich
        {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
95 7528fc09 Scott Ullrich
        break;}}
96
	if (!empty($post['dhcp_wins'])) {
97 f9927473 Scott Ullrich
    $servers = explode(';', $post['dhcp_wins']);
98 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
99 f9927473 Scott Ullrich
        {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
100 7528fc09 Scott Ullrich
        break;}}
101
	if (!empty($post['dhcp_nbdd'])) {
102 f9927473 Scott Ullrich
    $servers = explode(';', $post['dhcp_nbdd']);
103 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
104 f9927473 Scott Ullrich
        {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
105 7528fc09 Scott Ullrich
        break;}}
106
	if (!empty($post['dhcp_ntp'])) {
107 f9927473 Scott Ullrich
    $servers = explode(';', $post['dhcp_ntp']);
108 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
109 f9927473 Scott Ullrich
        {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
110 7528fc09 Scott Ullrich
        break;}}
111 54816afd Martin Fuchs
	if (isset($post['maxclients']) && $post['maxclients'] != "") {
112
		if (!is_numeric($post['maxclients']))
113
			$input_errors[] = 'The field \'Maximum clients\' must be numeric.';
114 6d031071 Martin Fuchs
		}
115 f9927473 Scott Ullrich
116 add2e3f7 Scott Ullrich
	}
117
118 8dc3ef67 Scott Ullrich
	else { // Client mode
119
		if ($result = openvpn_validate_port($post['serverport'], 'Server port'))
120
			$input_errors[] = $result;
121
122 add2e3f7 Scott Ullrich
		$server_addr = trim($post['serveraddr']);
123 8dc3ef67 Scott Ullrich
		if (!empty($value) && !(is_domain($server_addr) || is_ipaddr($server_addr)))
124 add2e3f7 Scott Ullrich
			$input_errors[] = 'The field \'Server address\' must contain a valid IP address or domain name.';
125
126 8dc3ef67 Scott Ullrich
		if ($result = openvpn_validate_cidr($post['interface_ip'], 'Interface IP'))
127
			$input_errors[] = $result;
128
129
		if ($post['auth_method'] == 'shared_key') {
130
			if (empty($post['interface_ip']))
131
				$input_errors[] = 'The field \'Interface IP\' is required.';
132
		}
133
		if (isset($post['proxy_hostname']) && $post['proxy_hostname'] != "") {
134
			if (!is_domain($post['proxy_hostname']) || is_ipaddr($post['proxy_hostname']))
135
				$input_errors[] = 'The field \'Proxy Host\' must contain a valid IP address or domain name.';
136
			if (!is_port($post['proxy_port']))
137
				$input_errors[] = 'The field \'Proxy port\' must contain a valid port number.';
138 24012690 Scott Ullrich
			if ($post['protocol'] != "TCP")
139 8dc3ef67 Scott Ullrich
				$input_errors[] = 'The protocol must be TCP to use a HTTP proxy server.';
140
		}
141 db9aabe2 Scott Ullrich
		if (isset($post['use_shaper']) && $post['use_shaper'] != "") {
142
			if (!is_numeric($post['use_shaper']))
143 c1a4aaca Martin Fuchs
				$input_errors[] = 'The field \'Limit outgoing bandwidth\' must be numeric.';
144 db9aabe2 Scott Ullrich
		}
145 24012690 Scott Ullrich
146 add2e3f7 Scott Ullrich
	}
147
148 8dc3ef67 Scott Ullrich
	if ($result = openvpn_validate_cidr($post['remote_network'], 'Remote network'))
149
		$input_errors[] = $result;
150
151 add2e3f7 Scott Ullrich
	if ($_POST['auth_method'] == 'shared_key') {
152
		$reqfields[] = 'shared_key';
153
		$reqfieldsn[] = 'Shared key';
154
	}
155
	else {
156
		$req = explode(' ', "ca_cert {$mode}_cert {$mode}_key");
157
		$reqn = array(	'CA certificate',
158
				ucfirst($mode) . ' certificate',
159
				ucfirst($mode) . ' key');
160
		$reqfields = array_merge($reqfields, $req);
161
		$reqfieldsn = array_merge($reqfieldsn, $reqn);
162
		if ($mode == 'server') {
163
			$reqfields[] = 'dh_params';
164
			$reqfieldsn[] = 'DH parameters';
165
		}
166
	}
167
	do_input_validation($post, $reqfields, $reqfieldsn, &$input_errors);
168
169 eff83433 Martin Fuchs
//  if ($post['protocol'] != 'UDP') {
170
//    if (!empty($post['tls']))
171
//        $input_errors[] = 'TLS-authentication can only be used with protocol UDP';
172
//        }
173 54816afd Martin Fuchs
174 add2e3f7 Scott Ullrich
	$value = trim($post['shared_key']);
175
	$items = array();
176 54816afd Martin Fuchs
177 add2e3f7 Scott Ullrich
	if ($_POST['auth_method'] == 'shared_key') {
178
		$items[] = array(	'field' => 'shared_key',
179
					'string' => 'OpenVPN Static key V1',
180
					'name' => 'Shared key');
181
	}
182
	else {
183
		$items[] = array(	'field' => 'ca_cert',
184
					'string' => 'CERTIFICATE',
185
					'name' => 'CA certificate');
186
		$items[] = array(	'field' => "{$mode}_cert",
187
					'string' => 'CERTIFICATE',
188
					'name' => "$Mode certificate");
189
		$items[] = array(	'field' => "{$mode}_key",
190
					'string' => 'RSA PRIVATE KEY',
191
					'name' => "$Mode key");
192 54816afd Martin Fuchs
	  $items[] = array(	'field' => 'tls',
193
		      'string' => 'OpenVPN Static key V1',
194 6d031071 Martin Fuchs
		      'name' => 'TLS');
195 add2e3f7 Scott Ullrich
		if ($mode == 'server') {
196
			$items[] = array(	'field' => 'dh_params',
197
						'string' => 'DH PARAMETERS',
198
						'name' => 'DH parameters');
199
			$items[] = array(	'field' => 'crl',
200
						'string' => 'X509 CRL',
201
						'name' => 'CRL');
202
		}
203
	}
204
	foreach ($items as $item) {
205
		$value = trim($_POST[$item['field']]);
206
		$string = $item['string'];
207
		if ($value && (!strstr($value, "-----BEGIN {$string}-----") || !strstr($value, "-----END {$string}-----")))
208
			$input_errors[] = "The field '{$item['name']}' does not appear to be valid";
209
	}
210
}
211
212
213 8dc3ef67 Scott Ullrich
function openvpn_validate_input_csc($post, $input_errors) {
214
	if ($result = openvpn_validate_cidr($post['ifconfig_push'], 'Interface IP'))
215
		$input_errors[] = $result;
216
217 54816afd Martin Fuchs
	if ($post['push_reset'] != 'on') {
218
    if (!empty($post['dhcp_domainname']))
219
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
220
    elseif (!empty($post['dhcp_dns']))
221
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
222
    elseif (!empty($post['dhcp_wins']))
223
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
224
    elseif (!empty($post['dhcp_nbdd']))
225
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
226
    elseif (!empty($post['dhcp_ntp']))
227
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
228
    elseif ($post['dhcp_nbttype'])
229
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
230
    elseif (!empty($post['dhcp_nbtscope']))
231 6d031071 Martin Fuchs
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
232 54816afd Martin Fuchs
    elseif ($post['dhcp_nbtdisable'])
233 6d031071 Martin Fuchs
        $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
234 54816afd Martin Fuchs
235
  }
236
  else {
237
238
	if (!empty($post['dhcp_dns'])) {
239
    $servers = explode(';', $post['dhcp_dns']);
240 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
241 54816afd Martin Fuchs
        {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
242
        break;}}
243
	if (!empty($post['dhcp_wins'])) {
244
    $servers = explode(';', $post['dhcp_wins']);
245 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
246 54816afd Martin Fuchs
        {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
247
        break;}}
248
	if (!empty($post['dhcp_nbdd'])) {
249
    $servers = explode(';', $post['dhcp_nbdd']);
250 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
251 54816afd Martin Fuchs
        {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
252
        break;}}
253
	if (!empty($post['dhcp_ntp'])) {
254
    $servers = explode(';', $post['dhcp_ntp']);
255 6d031071 Martin Fuchs
      foreach ($servers as $server) if (!is_ipaddr($server))
256 54816afd Martin Fuchs
        {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
257 6d031071 Martin Fuchs
        break;}}
258
259 54816afd Martin Fuchs
}}
260 8dc3ef67 Scott Ullrich
261 add2e3f7 Scott Ullrich
// Rewrite the settings
262
function openvpn_reconfigure($mode, $id) {
263
	global $g, $config;
264 afb07cf1 Scott Ullrich
265 add2e3f7 Scott Ullrich
	$settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
266
	if ($settings['disable']) return;
267
268 d8576be5 Scott Ullrich
	$lport = 1194 + $id;
269
270 8dc3ef67 Scott Ullrich
	// Set the keys up
271
	// Note that the keys' extension is also the directive that goes to the config file
272 add2e3f7 Scott Ullrich
	$base_file = $g['varetc_path'] . "/openvpn_{$mode}{$id}.";
273
	$keys = array();
274
	if ($settings['auth_method'] == 'shared_key')
275
		$keys[] = array('field' => 'shared_key', 'ext'  => 'secret', 'directive' => 'secret');
276
	else {
277
		$keys[] = array('field' => 'ca_cert', 'ext' => 'ca', 'directive' => 'ca');
278
		$keys[] = array('field' => "{$mode}_cert", 'ext' => 'cert', 'directive' => 'cert');
279
		$keys[] = array('field' => "{$mode}_key", 'ext' => 'key', 'directive' => 'key');
280
		if ($mode == 'server')
281
			$keys[] = array('field' => 'dh_params', 'ext' => 'dh', 'directive' => 'dh');
282
		if ($settings['crl'])
283
			$keys[] = array('field' => 'crl', 'ext' => 'crl', 'directive' => 'crl-verify');
284 54816afd Martin Fuchs
		if ($settings['tls'])
285
		  $keys[] = array('field' => 'tls', 'ext' => 'tls', 'directive' => 'tls-auth');
286 6d031071 Martin Fuchs
287 add2e3f7 Scott Ullrich
	}
288
	foreach($keys as $key) {
289
		$filename = $base_file . $key['ext'];
290
		file_put_contents($filename, base64_decode($settings[$key['field']]));
291
		chown($filename, 'nobody');
292
		chgrp($filename, 'nobody');
293
	}
294
295 8dc3ef67 Scott Ullrich
	$pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
296 add2e3f7 Scott Ullrich
	$proto = ($settings['protocol'] == 'UDP' ? 'udp' : "tcp-{$mode}");
297
	$cipher = $settings['crypto'];
298
	$openvpn_conf = <<<EOD
299 8dc3ef67 Scott Ullrich
writepid $pidfile
300 344b0230 Scott Ullrich
#user nobody
301
#group nobody
302 add2e3f7 Scott Ullrich
daemon
303
keepalive 10 60
304
ping-timer-rem
305 afb07cf1 Scott Ullrich
persist-tun
306
persist-key
307 add2e3f7 Scott Ullrich
dev tun
308
proto $proto
309
cipher $cipher
310 2f0a7613 Scott Ullrich
up /etc/rc.filter_configure
311
down /etc/rc.filter_configure
312 afb07cf1 Scott Ullrich
313
EOD;
314 8dc3ef67 Scott Ullrich
315
	// Mode-specific stuff
316
	if ($mode == 'server') {
317
		list($ip, $mask) = explode('/', $settings['addresspool']);
318
		$mask = gen_subnet_mask($mask);
319
320
		// Using a shared key or not dynamically assigning IPs to the clients
321
		if (($settings['auth_method'] == 'shared_key') || ($settings['nopool'] == 'on')) {
322
			if ($settings['auth_method'] == 'pki') $openvpn_conf .= "tls-server\n";
323
324
			$baselong = ip2long($ip) & ip2long($mask);
325
			$ip1 = long2ip($baselong + 1);
326
			$ip2 = long2ip($baselong + 2);
327
			$openvpn_conf .= "ifconfig $ip1 $ip2\n";
328
		}
329
		// Using a PKI
330
		else if ($settings['auth_method'] == 'pki') {
331
			if ($settings['client2client']) $openvpn_conf .= "client-to-client\n";
332
			$openvpn_conf .= "server $ip $mask\n";
333
			$csc_dir = "{$g['varetc_path']}/openvpn_csc";
334
			$openvpn_conf .= "client-config-dir $csc_dir\n";
335
		}
336
337
		// We can push routes
338
		if (!empty($settings['local_network'])) {
339
			list($ip, $mask) = explode('/', $settings['local_network']);
340
			$mask = gen_subnet_mask($mask);
341
			$openvpn_conf .= "push \"route $ip $mask\"\n";
342
		}
343
344 62366828 Martin Fuchs
        if ($settings['bind_to_iface'] == 'on') {
345
            $iface = $settings['interface'];
346
            $iface = convert_friendly_interface_to_real_interface_name($iface);
347
            $line = trim(shell_exec("ifconfig $iface | grep inet | grep -v inet6"));
348
            list($dummy, $ip, $dummy2, $dummy3) = explode(' ', $line);
349
350
            $openvpn_conf .= "local {$ip}\n";
351
        }
352
353 8dc3ef67 Scott Ullrich
		// The port we'll listen at
354
		$openvpn_conf .= "lport {$settings['local_port']}\n";
355 ee506044 Scott Ullrich
356 f9927473 Scott Ullrich
		// DHCP-Options
357
	  if (!empty($settings['dhcp_domainname'])) $openvpn_conf .= "push \"dhcp-option DOMAIN {$settings['dhcp_domainname']}\"\n";
358 6d031071 Martin Fuchs
359 f9927473 Scott Ullrich
    if (!empty($settings['dhcp_dns'])) {
360
	   	$servers = explode(';', $settings['dhcp_dns']);
361
   	  if (is_array($servers)) {
362
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option DNS {$server}\"\n";
363
  	  }
364
		  else {
365
			$openvpn_conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
366
		  }
367
    }
368 6d031071 Martin Fuchs
369 f9927473 Scott Ullrich
    if (!empty($settings['dhcp_wins'])) {
370
	   	$servers = explode(';', $settings['dhcp_wins']);
371
   	  if (is_array($servers)) {
372
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option WINS {$server}\"\n";
373
  	  }
374
		  else {
375
			$openvpn_conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
376
		  }
377 6d031071 Martin Fuchs
    }
378 f9927473 Scott Ullrich
379
    if (!empty($settings['dhcp_nbdd'])) {
380
	   	$servers = explode(';', $settings['dhcp_nbdd']);
381
   	  if (is_array($servers)) {
382
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NBDD {$server}\"\n";
383
  	  }
384
		  else {
385
			$openvpn_conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
386
		  }
387 6d031071 Martin Fuchs
    }
388 f9927473 Scott Ullrich
389
    if (!empty($settings['dhcp_ntp'])) {
390
	   	$servers = explode(';', $settings['dhcp_ntp']);
391
   	  if (is_array($servers)) {
392
			 foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NTP {$server}\"\n";
393
  	  }
394
		  else {
395
			$openvpn_conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
396
		  }
397 6d031071 Martin Fuchs
    }
398 f9927473 Scott Ullrich
399
  	if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $openvpn_conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
400
    if (!empty($settings['dhcp_nbtscope'])) $openvpn_conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
401
   	if ($settings['dhcp_nbtdisable']) $openvpn_conf .= "push \"dhcp-option DISABLE-NBT\"\n";
402
403 54816afd Martin Fuchs
    if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_server{$id}.tls 0\n";
404
		if (!empty($settings['maxclients'])) $openvpn_conf .= "max-clients {$settings['maxclients']}\n";
405
			}
406 8dc3ef67 Scott Ullrich
407
	else { // $mode == client
408
		// The remote server
409
		$openvpn_conf .= "remote {$settings['serveraddr']} {$settings['serverport']}\n";
410
411
		if ($settings['auth_method'] == 'pki') $openvpn_conf .= "client\n";
412 ee506044 Scott Ullrich
		if ($settings['use_dynamicport']) $openvpn_conf .= "nobind\n";
413
			else
414
			// The port we'll listen at
415
			$openvpn_conf .= "lport {$lport}\n";
416
417 12415bd8 Scott Ullrich
		if (!empty($settings['use_shaper'])) $openvpn_conf .= "shaper {$settings['use_shaper']}\n";
418
419 8dc3ef67 Scott Ullrich
		if (!empty($settings['interface_ip'])) {
420
			// Configure the IPs according to the address pool
421
			list($ip, $mask) = explode('/', $settings['interface_ip']);
422
			$mask = gen_subnet_mask($mask);
423
			$baselong = ip2long($ip) & ip2long($mask);
424
			$ip1 = long2ip($baselong + 1);
425
			$ip2 = long2ip($baselong + 2);
426
			$openvpn_conf .= "ifconfig $ip2 $ip1\n";
427
		}
428
		if (isset($settings['proxy_hostname']) && $settings['proxy_hostname'] != "") {
429
			/* ;http-proxy-retry # retry on connection failures */
430
			$openvpn_conf .= "http-proxy {$settings['proxy_hostname']} {$settings['proxy_port']}\n";
431
		}
432 54816afd Martin Fuchs
433
    if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_client{$id}.tls 1\n";
434
435 8dc3ef67 Scott Ullrich
	}
436
437
	// Add the routes if they're set
438
	if (!empty($settings['remote_network'])) {
439
		list($ip, $mask) = explode('/', $settings['remote_network']);
440
		$mask = gen_subnet_mask($mask);
441
		$openvpn_conf .= "route $ip $mask\n";
442
	}
443 afb07cf1 Scott Ullrich
444 add2e3f7 Scott Ullrich
	// Write the settings for the keys
445
	foreach ($keys as $key)
446 54816afd Martin Fuchs
  if ($key['directive'] != 'tls-auth') {
447 add2e3f7 Scott Ullrich
		$openvpn_conf .= $key['directive'] . ' ' . $base_file . $key['ext'] . "\n";
448 54816afd Martin Fuchs
    }
449 707e9964 Scott Ullrich
450 add2e3f7 Scott Ullrich
	if ($settings['use_lzo']) $openvpn_conf .= "comp-lzo\n";
451 8dc3ef67 Scott Ullrich
452 8fc63cd8 Martin Fuchs
	if ($settings['passtos']) $openvpn_conf .= "passtos\n";
453
454 8dc3ef67 Scott Ullrich
	if ($settings['dynamic_ip']) {
455
		$openvpn_conf .= "persist-remote-ip\n";
456
		$openvpn_conf .= "float\n";
457
	}
458
459
	if (!empty($settings['custom_options'])) {
460
		$options = explode(';', $settings['custom_options']);
461
		if (is_array($options)) {
462
			foreach ($options as $option)
463
				$openvpn_conf .= "$option\n";
464
		}
465
		else {
466
			$openvpn_conf .= "{$settings['custom_options']}\n";
467
		}
468
	}
469 afb07cf1 Scott Ullrich
470 add2e3f7 Scott Ullrich
	file_put_contents($g['varetc_path'] . "/openvpn_{$mode}{$id}.conf", $openvpn_conf);
471 afb07cf1 Scott Ullrich
}
472
473
474 8dc3ef67 Scott Ullrich
function openvpn_resync_csc($id) {
475
	global $g, $config;
476
477
	$settings = $config['installedpackages']['openvpncsc']['config'][$id];
478
479 c876662c Scott Ullrich
	if ($settings['disable'] == 'on') {
480
		$filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
481
		unlink_if_exists($filename);
482
		return;
483
	}
484
	
485 8dc3ef67 Scott Ullrich
	$conf = '';
486
	if ($settings['block'] == 'on') $conf .= "disable\n";
487
	if ($settings['push_reset'] == 'on') $conf .= "push-reset\n";
488
	if (!empty($settings['ifconfig_push'])) {
489
		list($ip, $mask) = explode('/', $settings['ifconfig_push']);
490
		$baselong = ip2long($ip) & gen_subnet_mask_long($mask);
491
		$conf .= 'ifconfig-push ' . long2ip($baselong + 1) . ' ' . long2ip($baselong + 2) . "\n";
492
	}
493 6d031071 Martin Fuchs
494 54816afd Martin Fuchs
// DHCP-Options
495
	  if (!empty($settings['dhcp_domainname'])) $conf .= "push \"dhcp-option DOMAIN {$settings['dhcp_domainname']}\"\n";
496 6d031071 Martin Fuchs
497 54816afd Martin Fuchs
    if (!empty($settings['dhcp_dns'])) {
498
	   	$servers = explode(';', $settings['dhcp_dns']);
499
   	  if (is_array($servers)) {
500
			 foreach ($servers as $server) $conf .= "push \"dhcp-option DNS {$server}\"\n";
501
  	  }
502
		  else {
503
			$conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
504
		  }
505
    }
506 6d031071 Martin Fuchs
507 54816afd Martin Fuchs
    if (!empty($settings['dhcp_wins'])) {
508
	   	$servers = explode(';', $settings['dhcp_wins']);
509
   	  if (is_array($servers)) {
510
			 foreach ($servers as $server) $conf .= "push \"dhcp-option WINS {$server}\"\n";
511
  	  }
512
		  else {
513
			$conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
514
		  }
515 6d031071 Martin Fuchs
    }
516 54816afd Martin Fuchs
517
    if (!empty($settings['dhcp_nbdd'])) {
518
	   	$servers = explode(';', $settings['dhcp_nbdd']);
519
   	  if (is_array($servers)) {
520
			 foreach ($servers as $server) $conf .= "push \"dhcp-option NBDD {$server}\"\n";
521
  	  }
522
		  else {
523
			$conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
524
		  }
525 6d031071 Martin Fuchs
    }
526 54816afd Martin Fuchs
527
    if (!empty($settings['dhcp_ntp'])) {
528
	   	$servers = explode(';', $settings['dhcp_ntp']);
529
   	  if (is_array($servers)) {
530
			 foreach ($servers as $server) $conf .= "push \"dhcp-option NTP {$server}\"\n";
531
  	  }
532
		  else {
533
			$conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
534
		  }
535 6d031071 Martin Fuchs
    }
536 54816afd Martin Fuchs
537
  	if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
538
    if (!empty($settings['dhcp_nbtscope'])) $conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
539
   	if ($settings['dhcp_nbtdisable']) $conf .= "push \"dhcp-option DISABLE-NBT\"\n";
540
541 6d031071 Martin Fuchs
542 8dc3ef67 Scott Ullrich
	if (!empty($settings['custom_options'])) {
543
		$options = explode(';', $settings['custom_options']);
544
		if (is_array($options)) {
545
			foreach ($options as $option)
546
				$conf .= "$option\n";
547
		}
548
		else {
549
			$conf .= "{$settings['custom_options']}\n";
550
		}
551
	}
552
553
	$filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
554
	file_put_contents($filename, $conf);
555
	chown($filename, 'nobody');
556
	chgrp($filename, 'nogroup');
557 6d031071 Martin Fuchs
558 8dc3ef67 Scott Ullrich
}
559
560
561 add2e3f7 Scott Ullrich
function openvpn_restart($mode, $id) {
562
	global $g, $config;
563 3c2e5528 Scott Ullrich
564 add2e3f7 Scott Ullrich
	$pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
565
	killbypid($pidfile);
566
	sleep(2);
567 afb07cf1 Scott Ullrich
568 add2e3f7 Scott Ullrich
	$settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
569
	if ($settings['disable']) return;
570 afb07cf1 Scott Ullrich
571 add2e3f7 Scott Ullrich
	$configfile = $g['varetc_path'] . "/openvpn_{$mode}{$id}.conf";
572 481fda7f Scott Ullrich
	mwexec_bg("nohup openvpn --config $configfile");
573 ffb47da1 Scott Ullrich
	touch("{$g['tmp_path']}/filter_dirty");
574 afb07cf1 Scott Ullrich
}
575
576
577 24012690 Scott Ullrich
// Resync the configuration and restart the VPN
578 add2e3f7 Scott Ullrich
function openvpn_resync($mode, $id) {
579
	openvpn_reconfigure($mode, $id);
580
	openvpn_restart($mode, $id);
581 afb07cf1 Scott Ullrich
}
582
583 8dc3ef67 Scott Ullrich
function openvpn_create_cscdir() {
584
	global $g;
585
586
	$csc_dir = "{$g['varetc_path']}/openvpn_csc";
587 36df0acc Scott Ullrich
	if (is_dir($csc_dir))
588
		rmdir_recursive($csc_dir);
589
	make_dirs($csc_dir);
590
	chown($csc_dir, 'nobody');
591
	chgrp($csc_dir, 'nobody');
592 8dc3ef67 Scott Ullrich
}
593 afb07cf1 Scott Ullrich
594 add2e3f7 Scott Ullrich
// Resync and restart all VPNs
595
function openvpn_resync_all() {
596 3c2e5528 Scott Ullrich
	global $config;
597 afb07cf1 Scott Ullrich
598 add2e3f7 Scott Ullrich
	foreach (array('server', 'client') as $mode) {
599
		if (is_array($config['installedpackages']["openvpn$mode"]['config'])) {
600
			foreach ($config['installedpackages']["openvpn$mode"]['config'] as $id => $settings)
601
				openvpn_resync($mode, $id);
602 3c2e5528 Scott Ullrich
		}
603
	}
604 8dc3ef67 Scott Ullrich
605
	openvpn_create_cscdir();
606
	if (is_array($config['installedpackages']['openvpncsc']['config'])) {
607
		foreach ($config['installedpackages']['openvpncsc']['config'] as $id => $csc)
608
			openvpn_resync_csc($id);
609
	}
610 6d031071 Martin Fuchs
611 48f4405e Scott Ullrich
	/* give speedy machines time to settle */
612
	sleep(5);
613 6d031071 Martin Fuchs
614 48f4405e Scott Ullrich
	/* reload the filter policy */
615
	filter_configure();
616 6d031071 Martin Fuchs
617 afb07cf1 Scott Ullrich
}
618
619 add2e3f7 Scott Ullrich
function openvpn_print_javascript($mode) {
620
	$javascript = <<<EOD
621
<script language="JavaScript">
622
<!--
623
function onAuthMethodChanged() {
624 83305ae3 Scott Ullrich
	var method = document.iform.auth_method;
625
	var endis = (method.options[method.selectedIndex].value == 'shared_key');
626
627 add2e3f7 Scott Ullrich
	document.iform.shared_key.disabled = !endis;
628
	document.iform.ca_cert.disabled = endis;
629
	document.iform.{$mode}_cert.disabled = endis;
630
	document.iform.{$mode}_key.disabled = endis;
631 6d031071 Martin Fuchs
    document.iform.tls.disabled = endis;
632 afb07cf1 Scott Ullrich
633
EOD;
634 add2e3f7 Scott Ullrich
	if ($mode == 'server') {
635 8dc3ef67 Scott Ullrich
		$javascript .= <<<EOD
636
	document.iform.dh_params.disabled = endis;
637
	document.iform.crl.disabled = endis;
638 54816afd Martin Fuchs
	document.iform.tls.disabled = endis;
639 8dc3ef67 Scott Ullrich
	document.iform.nopool.disabled = endis;
640
	document.iform.local_network.disabled = endis;
641
	document.iform.client2client.disabled = endis;
642 54816afd Martin Fuchs
	document.iform.maxclients.disabled = endis;
643 8dc3ef67 Scott Ullrich
644
EOD;
645
	}
646
647
	else { // Client mode
648
		$javascript .= "\tdocument.iform.remote_network.disabled = !endis;\n";
649 afb07cf1 Scott Ullrich
	}
650 8dc3ef67 Scott Ullrich
651 add2e3f7 Scott Ullrich
	$javascript .= <<<EOD
652 5b237745 Scott Ullrich
}
653 add2e3f7 Scott Ullrich
//-->
654
</script>
655 5b237745 Scott Ullrich
656 add2e3f7 Scott Ullrich
EOD;
657
	print($javascript);
658 afb07cf1 Scott Ullrich
}
659
660
661 add2e3f7 Scott Ullrich
function openvpn_print_javascript2() {
662
	$javascript = <<<EOD
663
<script language="JavaScript">
664
<!--
665
	onAuthMethodChanged();
666
//-->
667
</script>
668 5b237745 Scott Ullrich
669 add2e3f7 Scott Ullrich
EOD;
670
	print($javascript);
671 5b237745 Scott Ullrich
}
672 c1a4aaca Martin Fuchs
?>