Project

General

Profile

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

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu�i
8
	All rights reserved.
9

    
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13

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

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

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

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

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	$cfgtext = array();
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (!isset($config['ipsec']["ipsec_{$lkey}"]) && !$forconfig)
52
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -- -1", false);
53
		else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
54
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 0 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5)
55
			$forconfig ? $cfgtext[] = "${lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) :
56
				mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
57
	}
58
	if ($forconfig)
59
		return implode(',', $cfgtext);
60
}
61

    
62
/* include all configuration functions */
63
function vpn_ipsec_convert_to_modp($index)
64
{
65

    
66
	$convertion = "";
67
	switch ($index) {
68
	case '1':
69
		$convertion = "modp768";
70
		break;
71
	case '2':
72
		$convertion = "modp1024";
73
		break;
74
	case '5':
75
		$convertion = "modp1536";
76
		break;
77
	case '14':
78
		$convertion = "modp2048";
79
		break;
80
	case '15':
81
		$convertion = "modp3072";
82
		break;
83
	case '16':      
84
		$convertion = "modp4096";
85
		break;
86
	case '17':
87
		$convertion = "modp6144";
88
		break;
89
	case '18':
90
		$convertion = "modp8192";
91
		break;
92
	}
93

    
94
	return $convertion;
95
}
96

    
97
function vpn_ipsec_configure($restart = false)
98
{
99
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
100

    
101
	if ($g['platform'] == 'jail')
102
		return;
103

    
104
	/* get the automatic ping_hosts.sh ready */
105
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
106
	touch("{$g['vardb_path']}/ipsecpinghosts");
107

    
108
	vpn_ipsec_configure_preferoldsa();
109

    
110
	$syscfg = $config['system'];
111
	$ipseccfg = $config['ipsec'];
112
	if (!isset($ipseccfg['enable'])) {
113
		/* try to stop charon */
114
		mwexec("/usr/local/sbin/ipsec stop");
115
		/* Stop dynamic monitoring */
116
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
117

    
118
		/* wait for process to die */
119
		sleep(2);
120

    
121
		/* disallow IPSEC, it is off */
122
		mwexec("/sbin/ifconfig enc0 down");
123
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
124

    
125
		filter_configure();
126

    
127
		return 0;
128
	}
129

    
130
	$a_phase1 = $config['ipsec']['phase1'];
131
	$a_phase2 = $config['ipsec']['phase2'];
132
	$a_client = $config['ipsec']['client'];
133

    
134
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
135
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
136
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
137

    
138
	mwexec("/sbin/ifconfig enc0 up");
139
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
140
	/* needed for config files */
141
	if (!is_dir("{$g['varetc_path']}/ipsec"))
142
		mkdir("{$g['varetc_path']}/ipsec");
143
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d"))
144
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
145
	if (!is_dir($capath))
146
		mkdir($capath);
147
	if (!is_dir($keypath))
148
		mkdir($keypath);
149
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls"))
150
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
151
	if (!is_dir($certpath))
152
		mkdir($certpath);
153
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts"))
154
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
155
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts"))
156
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
157
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts"))
158
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
159
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs"))
160
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
161
	
162

    
163
	if (platform_booting())
164
		echo gettext("Configuring IPsec VPN... ");
165

    
166
	/* fastforwarding is not compatible with ipsec tunnels */
167
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
168

    
169
	/* resolve all local, peer addresses and setup pings */
170
	$ipmap = array();
171
	$rgmap = array();
172
	$filterdns_list = array();
173
	$listeniflist = array();
174
	$aggressive_mode_psk = false;
175
	unset($iflist);
176
	$ifacesuse = array();
177
	if (is_array($a_phase1) && count($a_phase1)) {
178

    
179
		$ipsecpinghosts = "";
180
		/* step through each phase1 entry */
181
		foreach ($a_phase1 as $ph1ent) {
182
			if (isset($ph1ent['disabled']))
183
				continue;
184

    
185
			if (strpos($ph1ent['interface'], '_vip')) {
186
				$vpninterface = explode('_vip', $ph1ent['interface']);
187
				$ifacesuse[] = get_real_interface($vpninterface[0]);
188
                        } else {
189
                                $vpninterface = get_failover_interface($ph1ent['interface']);
190
				if (!empty($vpninterface))
191
					$ifacesuse[] = $vpninterface;
192
			}
193
				
194
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) 
195
				$aggressive_mode_psk = true;
196

    
197
			$ikeid = $ph1ent['ikeid'];
198
			$listeniflist = get_real_interface($a_phase1['interface']);
199

    
200
			$ep = ipsec_get_phase1_src($ph1ent);
201
			if (!is_ipaddr($ep))
202
				continue;
203

    
204
			if(!in_array($ep,$ipmap))
205
				$ipmap[] = $ep;
206

    
207
			/* see if this tunnel has a hostname for the remote-gateway. If so,
208
			   try to resolve it now and add it to the list for filterdns */
209

    
210
			if (isset ($ph1ent['mobile']))
211
				continue;
212

    
213
			$rg = $ph1ent['remote-gateway'];
214

    
215
			if (!is_ipaddr($rg)) {
216
				$filterdns_list[] = "{$rg}";
217
				add_hostname_to_watch($rg);
218
				if (!platform_booting())
219
					$rg = resolve_retry($rg);
220
				if (!is_ipaddr($rg))
221
					continue;
222
			}
223
			if(array_search($rg, $rgmap)) {
224
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
225
				continue;
226
			}
227
			$rgmap[$ph1ent['remote-gateway']] = $rg;
228

    
229
			if (is_array($a_phase2)) {
230
				/* step through each phase2 entry */
231
				foreach ($a_phase2 as $ph2ent) {
232
					if (isset($ph2ent['disabled']))
233
						continue;
234

    
235
					if ($ikeid != $ph2ent['ikeid'])
236
						continue;
237

    
238
					/* add an ipsec pinghosts entry */
239
					if ($ph2ent['pinghost']) {
240
						if (!is_array($iflist))
241
							$iflist = get_configured_interface_list();
242
						$srcip = null;
243
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
244
						if(is_ipaddrv6($ph2ent['pinghost'])) {
245
							foreach ($iflist as $ifent => $ifname) {
246
								$interface_ip = get_interface_ipv6($ifent);
247
								if(!is_ipaddrv6($interface_ip))
248
									continue;
249
								if (ip_in_subnet($interface_ip, $local_subnet)) {
250
									$srcip = $interface_ip;
251
									break;
252
								}
253
							}
254
						} else {
255
							foreach ($iflist as $ifent => $ifname) {
256
								$interface_ip = get_interface_ip($ifent);
257
								if(!is_ipaddrv4($interface_ip))
258
									continue;
259
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
260
									$srcip = $interface_ip;
261
									break;
262
								}
263
							}
264
						}
265
						/* if no valid src IP was found in configured interfaces, try the vips */
266
						if (is_null($srcip)) {
267
							$viplist = get_configured_vips_list();
268
							foreach ($viplist as $vip) {
269
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
270
									$srcip = $vip['ipaddr'];
271
									break;
272
								}
273
							}
274
						}
275
						$dstip = $ph2ent['pinghost'];
276
						if(is_ipaddrv6($dstip)) {
277
							$family = "inet6";
278
						} else {
279
							$family = "inet";
280
						}
281
						if (is_ipaddr($srcip))
282
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
283
					}
284
				}
285
			}
286
		}
287
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
288
		unset($ipsecpinghosts);
289
	}
290
	unset($iflist);
291

    
292
	$accept_unencrypted = "";
293
	if (isset($config['ipsec']['acceptunencryptedmainmode']))
294
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
295

    
296
	$stronconf = '';
297
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf"))
298
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
299

    
300
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
301
	if ($aggressive_mode_psk) {
302
		log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
303
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE)
304
			$restart = true;
305
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
306
	} 
307

    
308
	$unity_enabled = 'yes';
309
	if (isset($config['ipsec']['unityplugin']))
310
		$unity_enabled = 'no';
311

    
312
	if (!empty($ifacesuse))
313
		$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
314
	else
315
		$ifacesuse = '';
316

    
317
	unset($stronconf);
318

    
319
	$strongswan = <<<EOD
320

    
321
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
322
starter {
323
load_warning = no
324
}
325

    
326
charon {
327
# number of worker threads in charon
328
threads = 16
329
ikesa_table_size = 32
330
ikesa_table_segments = 4
331
init_limit_half_open = 1000
332
install_routes = no
333
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
334
{$accept_unencrypted}
335
cisco_unity = {$unity_enabled}
336
{$ifacesuse}
337

    
338
# And two loggers using syslog. The subsections define the facility to log
339
# to, currently one of: daemon, auth.
340
syslog {
341
	identifier = charon
342
	# default level to the LOG_DAEMON facility
343
	daemon {
344
	}
345
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
346
	auth {
347
		default = -1
348
		ike = 1
349
		ike_name = yes
350
	}
351
}
352

    
353
EOD;
354

    
355
	$strongswan .= "\tplugins {\n";
356

    
357
	if (is_array($a_client) && isset($a_client['enable'])) {
358
		$strongswan .= "\t\tattr {\n";
359
		if ($a_client['pool_address'] && $a_client['pool_netbits'])
360
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
361

    
362
		$cfgservers = array();
363
		if (!empty($a_client['dns_server1']))
364
			$cfgservers[] = $a_client['dns_server1'];
365
		if (!empty($a_client['dns_server2']))
366
			$cfgservers[] = $a_client['dns_server2'];
367
		if (!empty($a_client['dns_server3']))
368
			$cfgservers[] = $a_client['dns_server3'];
369
		if (!empty($a_client['dns_server4']))
370
			$cfgservers[] = $a_client['dns_server4'];
371

    
372
		if (!empty($cfgservers))
373
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
374
		unset($cfgservers);
375
		$cfgservers = array();
376
		if (!empty($a_client['wins_server1']))
377
			$cfgservers[] = $a_client['wins_server1'];
378
		if (!empty($a_client['wins_server2']))
379
			$cfgservers[] = $a_client['wins_server2'];
380
		if (!empty($cfgservers))
381
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
382
		unset($cfgservers);
383

    
384
		if (isset($a_client['net_list'])) {
385
			$net_list = '';
386
			foreach ($a_phase2 as $ph2ent) {
387
				if (isset($ph2ent['disabled']))
388
					continue;
389

    
390
				if (!isset($ph2ent['mobile']))
391
					continue;
392

    
393
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
394

    
395
				if (!empty($net_list))
396
					$net_list .= ",";
397
				$net_list .= $localid;
398
			}
399

    
400
			if (!empty($net_list)) {
401
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
402
				unset($net_list);
403
			}
404
		}
405

    
406
		if (!empty($a_client['dns_domain'])) {
407
			$strongswan .= "\t\t\t# Search domain and default domain\n";
408
			$strongswan .= "\t\t\t28674 = {$a_client['dns_domain']}\n";
409
			if (empty($a_client['dns_split']))
410
				$strongswan .= "\t\t\t28675 = {$a_client['dns_domain']}";
411
			$strongswan .= "\n";
412
		}
413

    
414
		if (!empty($a_client['dns_split'])) {
415
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
416
		}
417

    
418
		if (!empty($a_client['login_banner']))
419
			$strongswan .= "\t\t\t28672 = {$a_client['login_banner']}\n";
420

    
421
		if (isset($a_client['save_passwd']))
422
			$strongswan .= "\t\t\t28673 = 1\n";
423

    
424
		if ($a_client['pfs_group'])
425
			$strongswan .= "\t\t\t28679 = {$a_client['pfs_group']}\n";
426
		$strongswan .= "\t\t}\n";
427

    
428
		if ($a_client['user_source'] != "none") {
429
			$strongswan .= "\t\txauth-generic {\n";
430
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
431
			$strongswan .= "\t\t\tauthcfg = ";
432
			$firstsed = 0;
433
			$authcfgs = explode(",", $a_client['user_source']);
434
			foreach ($authcfgs as $authcfg) {
435
				if ($firstsed > 0)
436
					$strongswan .= ",";
437
				if ($authcfg == "system")
438
					$authcfg = "Local Database";
439
				$strongswan .= $authcfg;
440
				$firstsed = 1;
441
			}
442
			$strongswan .= "\n";
443
			$strongswan .= "\t\t}\n";
444
		}
445
	}
446

    
447
	$strongswan .= "\t}\n}\n";
448
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
449
	unset($strongswan);
450

    
451
	/* generate CA certificates files */
452
	if (is_array($config['ca']) && count($config['ca'])) {
453
		foreach ($config['ca'] as $ca) {
454
			if (!isset($ca['crt'])) {
455
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
456
				continue;
457
			}
458
			$cert = base64_decode($ca['crt']);
459
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
460
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
461
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
462
				continue;
463
			}
464
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
465
			if (!@file_put_contents($fname, $cert)) {
466
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
467
				continue;
468
			}
469
			unset($cert);
470
		}
471
	}
472

    
473
	$pskconf = "";
474

    
475
	if (is_array($a_phase1) && count($a_phase1)) {
476
		foreach ($a_phase1 as $ph1ent) {
477

    
478
			if (isset($ph1ent['disabled']))
479
				continue;
480

    
481
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
482
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls'))) {
483
				$certline = '';
484

    
485
				$ikeid = $ph1ent['ikeid'];
486
				$cert = lookup_cert($ph1ent['certref']);
487

    
488
				if (!$cert) {
489
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
490
					continue;
491
				}
492

    
493
				@chmod($certpath, 0600);
494

    
495
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
496
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
497
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
498
					continue;
499
				}
500
				@chmod($ph1keyfile, 0600);
501

    
502
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
503
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
504
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
505
					@unlink($ph1keyfile);
506
					continue;
507
				}
508
				@chmod($ph1certfile, 0600);
509

    
510
				/* XXX" Traffic selectors? */
511
				$pskconf .= " : RSA {$ph1keyfile}\n";
512
			} else {
513
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
514
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
515

    
516
				if (empty($peerid_data))
517
					continue;
518

    
519
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
520
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
521
				if (!empty($ph1ent['pre-shared-key'])) {
522
					if ($myid_type == 'fqdn' && !empty($myid_data))
523
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
524
					else
525
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
526
				}
527
			}
528
		}
529
	}
530

    
531
	/* Add user PSKs */
532
	if (is_array($config['system']) && is_array($config['system']['user'])) {
533
		foreach ($config['system']['user'] as $user) {
534
			if (!empty($user['ipsecpsk'])) {
535
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
536
			}
537
		}
538
		unset($user);
539
	}
540

    
541
	/* add PSKs for mobile clients */
542
	if (is_array($ipseccfg['mobilekey'])) {
543
		foreach ($ipseccfg['mobilekey'] as $key) {
544
			if ($key['ident'] == "allusers")
545
				$key['ident'] = '%any';
546
			if (empty($key['type']))
547
				$key['type'] = 'PSK';
548
			$pskconf .= "%any {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
549
		}
550
		unset($key);
551
	}
552

    
553
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
554
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
555
	unset($pskconf);
556

    
557
	$uniqueids = 'yes';
558
	if (!empty($config['ipsec']['uniqueids'])) {
559
		if (in_array($uniqueids, $ipsec_idhandling))
560
			$uniqueids = $config['ipsec']['uniqueids'];
561
	}
562
	$natfilterrules = false;
563
	/* begin ipsec.conf */
564
	$ipsecconf = "";
565
	$enablecompression = false;
566
	if (is_array($a_phase1) && count($a_phase1))  {
567

    
568
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
569
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
570
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
571

    
572
		foreach ($a_phase1 as $ph1ent) {
573
			if (isset($ph1ent['disabled']))
574
				continue;
575

    
576
			if ($ph1ent['mode'] == "aggressive")
577
				$aggressive = "yes";
578
			else
579
				$aggressive = "no";
580

    
581
			$ep = ipsec_get_phase1_src($ph1ent);
582
			if (!$ep)
583
				continue;
584

    
585
			$ikeid = $ph1ent['ikeid'];
586
			$keyexchange = "ikev1";
587
			$passive = "route";
588
			if (!empty($ph1ent['iketype'])) {
589
				if ($ph1ent['iketype'] == "ikev2") {
590
					$keyexchange = "ikev2";
591
					//$passive = "start";
592
				} else if ($ph1ent['iketype'] == "auto")
593
					$keyexchange = "ike";
594
			}
595

    
596
			if (isset($ph1ent['mobile'])) {
597
				$right_spec = "%any";
598
				$passive = 'add';
599
			} else {
600
				if (isset($ph1ent['responderonly']))
601
					$passive = 'add';
602

    
603
				$right_spec = $ph1ent['remote-gateway'];
604
				if (is_ipaddr($right_spec))
605
					$sourcehost = $right_spec;
606
				else
607
					$sourcehost = $rgmap['remote-gateway'];
608

    
609
				if ($ph1ent['protocol'] == 'inet') {
610
					if (strpos($ph1ent['interface'], '_vip')) {
611
						$vpninterface = explode('_vip', $ph1ent['interface']);
612
						$ifacesuse = get_real_interface($vpninterface[0]);
613
						$vpninterface = $vpninterface[0];
614
					} else {
615
						$ifacesuse = get_failover_interface($ph1ent['interface']);
616
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
617
					}
618
					
619
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
620
						$gatewayip = get_interface_gateway($vpninterface);
621
						$interfaceip = get_interface_ip($vpninterface);
622
						$subnet_bits = get_interface_subnet($vpninterface);
623
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
624
						/* if the remote gateway is in the local subnet, then don't add a route */
625
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
626
							if (is_ipaddrv4($gatewayip)) {
627
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
628
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
629
							}
630
						}
631
					}
632
				} else if ($ph1ent['protocol'] == 'inet6') {
633
					if (strpos($ph1ent['interface'], '_vip')) {
634
						$vpninterface = explode('_vip', $ph1ent['interface']);
635
						$ifacesuse = get_real_interface($vpninterface[0]);
636
						$vpninterface = $vpninterface[0];
637
					} else {
638
						$ifacesuse = get_failover_interface($ph1ent['interface']);
639
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
640
					}
641
					
642
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
643
						$gatewayip = get_interface_gateway_v6($vpninterface);
644
						$interfaceip = get_interface_ipv6($vpninterface);
645
						$subnet_bits = get_interface_subnetv6($vpninterface);
646
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
647
						/* if the remote gateway is in the local subnet, then don't add a route */
648
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
649
							if (is_ipaddrv6($gatewayip)) {
650
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
651
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
652
							}
653
						}
654
					}
655
				}
656
			}
657

    
658
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
659
			if ($myid_type != 'address')
660
				$myid_data = "{$myid_type}:{$myid_data}";
661

    
662
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
663
			$peerid_spec = '';
664
			if (!isset($ph1ent['mobile'])) {
665
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
666
				if ($peerid_type != 'address')
667
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
668
				else
669
					$peerid_spec = $peerid_data;
670
			}
671

    
672
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
673
				$ealgosp1 = '';
674
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
675
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
676
				if ($ealg_kl)
677
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
678
				else
679
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
680

    
681
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
682
				if (!empty($modp))
683
					$ealgosp1 .= "-{$modp}";
684

    
685
				$ealgosp1 .= "!";
686
			}
687

    
688
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
689
				if ($passive == "route")
690
					$dpdline = "dpdaction = restart";
691
				else
692
					$dpdline = "dpdaction = clear";
693
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
694
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
695
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
696
			} else
697
				$dpdline = "dpdaction = none";
698

    
699
			$ikelifeline = '';
700
			if ($ph1ent['lifetime'])
701
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
702

    
703
			$rightsourceip = NULL;
704
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
705
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
706

    
707
			$authentication = "";
708
			switch ($ph1ent['authentication_method']) {
709
			case 'eap-mschapv2':
710
				if (isset($ph1ent['mobile'])) {
711
					$authentication = "eap_identity=%any\n\t";
712
					$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
713
					if (!empty($ph1ent['certref']))
714
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
715
				}
716
				break;
717
			case 'eap-tls':
718
				if (isset($ph1ent['mobile'])) {
719
					$authentication = "eap_identity=%identity\n\t";
720
					$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
721
					if (!empty($ph1ent['certref']))
722
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
723
				} else {
724
					$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
725
					if (!empty($ph1ent['certref']))
726
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
727
				}
728
				break;
729
			case 'xauth_rsa_server':
730
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
731
				$authentication .= "\n\trightauth2 = xauth-generic";
732
				if (!empty($ph1ent['certref']))
733
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
734
				break;
735
			case 'xauth_psk_server':
736
				$authentication = "leftauth = psk\n\trightauth = psk";
737
				$authentication .= "\n\trightauth2 = xauth-generic";
738
				break;
739
			case 'pre_shared_key':
740
				$authentication = "leftauth = psk\n\trightauth = psk";
741
				break;
742
			case 'rsasig':
743
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
744
				if (!empty($ph1ent['certref']))
745
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
746
				break;
747
			case 'hybrid_rsa_server':
748
				$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
749
				$authentication .= "\n\trightauth2 = xauth";
750
				if (!empty($ph1ent['certref']))
751
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
752
				break;
753
			}
754

    
755
			$left_spec = $ep;
756

    
757
			if (isset($ph1ent['reauth_enable']))
758
				$reauth = "reauth = no";
759
			else
760
				$reauth = "reauth = yes";
761
			if (isset($ph1ent['rekey_enable']))
762
				$rekey = "rekey = no";
763
			else
764
				$rekey = "rekey = yes";
765

    
766
			if ($ph1ent['nat_traversal'] == 'off')
767
				$forceencaps = 'forceencaps = no';
768
			else if ($ph1ent['nat_traversal'] == 'force')
769
				$forceencaps = 'forceencaps = yes';
770
			else
771
				$forceencaps = 'forceencaps = no';
772

    
773
			$ipseclifetime = 0;
774
			$rightsubnet_spec = array();
775
			$leftsubnet_spec = array();
776
			$reqids = array();
777
			$ealgoAHsp2arr = array();
778
			$ealgoESPsp2arr = array();
779
		if (is_array($a_phase2) && count($a_phase2)) {
780
			foreach ($a_phase2 as $ph2ent) {
781
				if ($ikeid != $ph2ent['ikeid'])
782
					continue;
783

    
784
				if (isset($ph2ent['disabled']))
785
					continue;
786

    
787
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
788
					continue;
789

    
790
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
791
					$tunneltype = "type = tunnel";
792

    
793
					$localid_type = $ph2ent['localid']['type'];
794
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
795

    
796
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
797
					if (($localid_type == "none" || $localid_type == "mobile")
798
					    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
799
						$left_spec = '%any';
800
					} else {
801
						if ($localid_type != "address") {
802
							$localid_type = "subnet";
803
						}
804
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
805
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
806
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
807
							continue;
808
						}
809
						if (!empty($ph2ent['natlocalid'])) {
810
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
811
							if ($ph2ent['natlocalid']['type'] != "address") {
812
								if (is_subnet($natleftsubnet_data))
813
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
814
							} else {
815
								if (is_ipaddr($natleftsubnet_data))
816
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
817
							}
818
							$natfilterrules = true;
819
						}
820
					}
821

    
822
					$leftsubnet_spec[] = $leftsubnet_data;
823

    
824
					if (!isset($ph2ent['mobile'])) {
825
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
826
						$rightsubnet_spec[] = $tmpsubnet;
827
					} else if (!empty($a_client['pool_address'])) {
828
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
829
					}
830
				} else {
831
					$tunneltype = "type = transport";
832

    
833
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
834
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
835
						$left_spec = "%any";
836
					} else {
837
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
838
						$leftsubnet_spec[] = $tmpsubnet;
839
					}
840

    
841
					if (!isset($ph2ent['mobile'])) {
842
						$rightsubnet_spec[] = $right_spec;
843
					}
844
				}
845

    
846
				if (isset($a_client['pfs_group']))
847
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
848

    
849
				if ($ph2ent['protocol'] == 'esp') {
850
					if (is_array($ph2ent['encryption-algorithm-option'])) {
851
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
852
							$ealg_id = $ealg['name'];
853
							$ealg_kl = $ealg['keylen'];
854

    
855
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
856
								if (empty($p2_ealgos) || !is_array($p2_ealgos))
857
									require("ipsec.inc");
858
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
859
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
860
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
861
								/* XXX: in some cases where include ordering is suspect these variables
862
								 * are somehow 0 and we enter this loop forever and timeout after 900
863
								 * seconds wrecking bootup */
864
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
865
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
866
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
867
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
868
												$halgo = str_replace('hmac_', '', $halgo);
869
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
870
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
871
												if (!empty($modp))
872
													$tmpealgo .= "-{$modp}";
873
												$ealgoESPsp2arr[] = $tmpealgo;
874
											}
875
										} else {
876
											$tmpealgo = "{$ealg_id}{$keylen}";
877
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
878
											if (!empty($modp))
879
												$tmpealgo .= "-{$modp}";
880
											$ealgoESPsp2arr[] = $tmpealgo;
881
										}
882
									}
883
								}
884
							} else {
885
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
886
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
887
										$halgo = str_replace('hmac_', '', $halgo);
888
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
889
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
890
										if (!empty($modp))
891
											$tmpealgo .= "-{$modp}";
892
										$ealgoESPsp2arr[] = $tmpealgo;
893
									}
894
								} else {
895
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
896
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
897
									if (!empty($modp))
898
										$tmpealgo .= "-{$modp}";
899
									$ealgoESPsp2arr[] = $tmpealgo;
900
								}
901
							}
902
						}
903
					}
904
				} else if ($ph2ent['protocol'] == 'ah') {
905
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
906
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
907
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
908
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
909
							if (!empty($modp))
910
								$tmpAHalgo = "-{$modp}";
911
							$ealgoAHsp2arr[] = $tmpAHalgo;
912
						}
913
					}
914
				}
915

    
916
				$reqids[] = $ph2ent['reqid'];
917

    
918
				if (!empty($ph2ent['lifetime'])) {
919
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
920
						$ipseclifetime = intval($ph2ent['lifetime']);
921
				}
922

    
923
			}
924
		}
925

    
926
			$ipsecconnect =<<<EOD
927
	fragmentation = yes
928
	keyexchange = {$keyexchange}
929
	{$reauth}
930
	{$forceencaps}
931
	{$rekey}
932
	installpolicy = yes
933
	{$tunneltype}
934
	{$dpdline}
935
	auto = {$passive}
936
	left = {$left_spec}
937
	right = {$right_spec}
938
	leftid = {$myid_data}
939

    
940
EOD;
941

    
942
			if (isset($config['ipsec']['compression'])) {
943
				$ipsecconnect .= "\tcompress = yes\n";
944
				$enablecompression = true;
945
			}
946
			if (!empty($ikelifeline))
947
				$ipsecconnect .= "\t{$ikelifeline}\n";
948
			if ($ipseclifetime > 0)
949
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
950
			if (!empty($rightsourceip))
951
				$ipsecconnect .= "{$rightsourceip}";
952
			if (!empty($ealgosp1))
953
				$ipsecconnect .= "\t{$ealgosp1}\n";
954
			if (!empty($ealgoAHsp2arr))
955
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
956
			if (!empty($ealgoESPsp2arr))
957
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
958
			if (!empty($authentication))
959
				$ipsecconnect .= "\t{$authentication}\n";
960
			if (!empty($peerid_spec))
961
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
962
			if ($keyexchange == 'ikev1')
963
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
964

    
965
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
966
				if (!empty($rightsubnet_spec)) {
967
					$ipsecfin = '';
968
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
969
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
970
						if (!empty($reqids[$idx]))
971
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
972
						$ipsecfin .= $ipsecconnect;
973
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
974
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
975
					}
976
				} else
977
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
978
			} else {
979
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
980
				if (!empty($reqids[$idx]))
981
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
982
				$ipsecfin .= $ipsecconnect;
983
				if (!empty($rightsubnet_spec)) {
984
					$tempsubnets = array();
985
					foreach ($rightsubnet_spec as $rightsubnet)
986
						$tempsubnets[$rightsubnet] = $rightsubnet;
987
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
988
					unset($tempsubnets, $rightsubnet);
989
				}
990
				if (!empty($leftsubnet_spec)) {
991
					$tempsubnets = array();
992
					foreach ($leftsubnet_spec as $leftsubnet)
993
						$tempsubnets[$leftsubnet] = $leftsubnet;
994
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
995
					unset($tempsubnets, $leftsubnet);
996
				}
997
			}
998
			$ipsecconf .= $ipsecfin;
999
			unset($ipsecfin);
1000

    
1001
		}
1002
	}
1003

    
1004
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1005
	unset($ipsecconf);
1006
	/* end ipsec.conf */
1007

    
1008
	if ($enablecompression === true)
1009
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1010
	else
1011
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1012

    
1013
	/* mange process */
1014
	if ($restart === true) {
1015
		mwexec("/usr/local/sbin/ipsec restart", false); 
1016
	} else {
1017
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1018
			/* Read secrets */
1019
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1020
			/* Update configuration changes */
1021
			mwexec("/usr/local/sbin/ipsec update", false);
1022
		} else {
1023
			mwexec("/usr/local/sbin/ipsec start", false); 
1024
		}
1025
	}
1026

    
1027
	if ($natfilterrules == true)
1028
		filter_configure();
1029
	/* start filterdns, if necessary */
1030
	if (count($filterdns_list) > 0) {
1031
		$interval = 60;
1032
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
1033
			$interval = $ipseccfg['dns-interval'];
1034

    
1035
		$hostnames = "";
1036
		array_unique($filterdns_list);
1037
		foreach ($filterdns_list as $hostname)
1038
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1039
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1040
		unset($hostnames);
1041

    
1042
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
1043
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1044
		else {
1045
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1046
		}
1047
	} else {
1048
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1049
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1050
	}
1051

    
1052
	if (platform_booting())
1053
		echo "done\n";
1054

    
1055
	return count($filterdns_list);
1056
}
1057

    
1058
/*
1059
 * Forcefully restart IPsec
1060
 * This is required for when dynamic interfaces reload
1061
 * For all other occasions the normal vpn_ipsec_configure()
1062
 * will gracefully reload the settings without restarting
1063
 */
1064
function vpn_ipsec_force_reload($interface = "") {
1065
	global $g, $config;
1066

    
1067
	$ipseccfg = $config['ipsec'];
1068

    
1069
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1070
		$found = false;
1071
		foreach ($ipseccfg['phase1'] as $ipsec) {
1072
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1073
				$found = true;
1074
				break;
1075
			}
1076
		}
1077
		if (!$found) {
1078
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1079
			return;
1080
		}
1081
	}
1082

    
1083
	/* if ipsec is enabled, start up again */
1084
	if (isset($ipseccfg['enable'])) {
1085
		log_error(gettext("Forcefully reloading IPsec"));
1086
		vpn_ipsec_configure();
1087
	}
1088
}
1089

    
1090
/* master setup for vpn (mpd) */
1091
function vpn_setup() {
1092
	global $g;
1093

    
1094
	if ($g['platform'] == 'jail')
1095
		return;
1096

    
1097
	/* start pptpd */
1098
	vpn_pptpd_configure();
1099

    
1100
	/* start pppoe server */
1101
	vpn_pppoes_configure();
1102

    
1103
	/* setup l2tp */
1104
	vpn_l2tp_configure();
1105
}
1106

    
1107
function vpn_netgraph_support() {
1108
	$iflist = get_configured_interface_list();
1109
	foreach ($iflist as $iface) {
1110
		$realif = get_real_interface($iface);
1111
		/* Get support for netgraph(4) from the nic */
1112
		$ifinfo = pfSense_get_interface_addresses($realif);
1113
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1114
			pfSense_ngctl_attach(".", $realif);
1115
	}
1116
}
1117

    
1118
function vpn_pptpd_configure() {
1119
	global $config, $g;
1120

    
1121
	$syscfg = $config['system'];
1122
	$pptpdcfg = $config['pptpd'];
1123

    
1124
	if (platform_booting()) {
1125
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1126
			return 0;
1127

    
1128
		if (platform_booting(true))
1129
			echo gettext("Configuring PPTP VPN service... ");
1130
	} else {
1131
		/* kill mpd */
1132
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1133

    
1134
		/* wait for process to die */
1135
		sleep(3);
1136

    
1137
		if (is_process_running("mpd -b")) {
1138
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1139
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1140
		}
1141

    
1142
		/* remove mpd.conf, if it exists */
1143
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1144
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1145
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1146
	}
1147

    
1148
	if (empty($pptpdcfg['n_pptp_units'])) {
1149
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1150
		return;
1151
	}
1152

    
1153
	/* make sure pptp-vpn directory exists */
1154
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1155
		mkdir("{$g['varetc_path']}/pptp-vpn");
1156

    
1157
	switch ($pptpdcfg['mode']) {
1158
		case 'server' :
1159
			/* write mpd.conf */
1160
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1161
			if (!$fd) {
1162
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1163
				return 1;
1164
			}
1165

    
1166
			$mpdconf = <<<EOD
1167
pptps:
1168

    
1169
EOD;
1170

    
1171
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1172
				$mpdconf .= "	load pt{$i}\n";
1173
			}
1174

    
1175
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1176

    
1177
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1178

    
1179
				$mpdconf .= <<<EOD
1180

    
1181
pt{$i}:
1182
	new -i pptpd{$i} pt{$i} pt{$i}
1183
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1184
	load pts
1185

    
1186
EOD;
1187
			}
1188

    
1189
			$mpdconf .=<<<EOD
1190

    
1191
pts:
1192
	set iface disable on-demand
1193
	set iface enable proxy-arp
1194
	set iface enable tcpmssfix
1195
	set iface idle 1800
1196
	set iface up-script /usr/local/sbin/vpn-linkup
1197
	set iface down-script /usr/local/sbin/vpn-linkdown
1198
	set bundle enable multilink
1199
	set bundle enable crypt-reqd
1200
	set link yes acfcomp protocomp
1201
	set link no pap chap
1202
	set link enable chap-msv2
1203
	set link mtu 1460
1204
	set link keep-alive 10 60
1205
	set ipcp yes vjcomp
1206
	set bundle enable compression
1207
	set ccp yes mppc
1208
	set ccp yes mpp-e128
1209
	set ccp yes mpp-stateless
1210

    
1211
EOD;
1212

    
1213
			if (!isset ($pptpdcfg['req128'])) {
1214
				$mpdconf .=<<<EOD
1215
	set ccp yes mpp-e40
1216
	set ccp yes mpp-e56
1217

    
1218
EOD;
1219
			}
1220

    
1221
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1222
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1223

    
1224
			if (!empty($pptpdcfg['dns1'])) {
1225
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1226
				if (!empty($pptpdcfg['dns2']))
1227
					$mpdconf .= " " . $pptpdcfg['dns2'];
1228
				$mpdconf .= "\n";
1229
			} elseif (isset ($config['dnsmasq']['enable'])) {
1230
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1231
				if ($syscfg['dnsserver'][0])
1232
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1233
				$mpdconf .= "\n";
1234
			} elseif (isset($config['unbound']['enable'])) {
1235
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1236
				if ($syscfg['dnsserver'][0])
1237
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1238
				$mpdconf .= "\n";
1239
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1240
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1241
			}
1242

    
1243
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1244
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1245
				$acctport = $authport + 1;
1246
				$mpdconf .=<<<EOD
1247
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1248

    
1249
EOD;
1250
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1251
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1252
				$acctport = $authport + 1;
1253
				$mpdconf .=<<<EOD
1254
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1255

    
1256
EOD;
1257
			}
1258
			$mpdconf .=<<<EOD
1259
	set radius retries 3
1260
	set radius timeout 10
1261
	set auth enable radius-auth
1262

    
1263
EOD;
1264

    
1265
				if (isset ($pptpdcfg['radius']['accounting'])) {
1266
					$mpdconf .=<<<EOD
1267
	set auth enable radius-acct
1268
	set radius acct-update 300
1269

    
1270
EOD;
1271
				}
1272
			}
1273

    
1274
			fwrite($fd, $mpdconf);
1275
			fclose($fd);
1276
			unset($mpdconf);
1277

    
1278
			/* write mpd.links */
1279
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1280
			if (!$fd) {
1281
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1282
				return 1;
1283
			}
1284

    
1285
			$mpdlinks = "";
1286

    
1287
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1288
				$mpdlinks .=<<<EOD
1289

    
1290
pt{$i}:
1291
	set link type pptp
1292
	set pptp enable incoming
1293
	set pptp disable originate
1294
	set pptp disable windowing
1295

    
1296
EOD;
1297
			}
1298

    
1299
			fwrite($fd, $mpdlinks);
1300
			fclose($fd);
1301
			unset($mpdlinks);
1302

    
1303
			/* write mpd.secret */
1304
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1305
			if (!$fd) {
1306
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1307
				return 1;
1308
			}
1309

    
1310
			$mpdsecret = "";
1311

    
1312
			if (is_array($pptpdcfg['user'])) {
1313
				foreach ($pptpdcfg['user'] as $user) {
1314
					$pass = str_replace('\\', '\\\\', $user['password']);
1315
					$pass = str_replace('"', '\"', $pass);
1316
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1317
				}
1318
			}
1319

    
1320
			fwrite($fd, $mpdsecret);
1321
			fclose($fd);
1322
			unset($mpdsecret);
1323
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1324

    
1325
			vpn_netgraph_support();
1326

    
1327
			/* fire up mpd */
1328
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -s pptps pptps");
1329

    
1330
			break;
1331

    
1332
		case 'redir' :
1333
			break;
1334
	}
1335

    
1336
	if (platform_booting())
1337
		echo "done\n";
1338

    
1339
	return 0;
1340
}
1341

    
1342
function vpn_pppoes_configure() {
1343
	global $config;
1344

    
1345
	if (is_array($config['pppoes']['pppoe'])) {
1346
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1347
			vpn_pppoe_configure($pppoe);
1348
	}
1349
}
1350

    
1351
function vpn_pppoe_configure(&$pppoecfg) {
1352
	global $config, $g;
1353

    
1354
	$syscfg = $config['system'];
1355

    
1356
	/* create directory if it does not exist */
1357
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1358
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1359

    
1360
	if (platform_booting()) {
1361
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1362
			return 0;
1363

    
1364
		echo gettext("Configuring PPPoE Server service... ");
1365
	} else {
1366
		/* kill mpd */
1367
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1368

    
1369
		/* wait for process to die */
1370
		sleep(2);
1371

    
1372
	}
1373

    
1374
	switch ($pppoecfg['mode']) {
1375

    
1376
		case 'server' :
1377

    
1378
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1379

    
1380
			if ($pppoecfg['paporchap'] == "chap")
1381
				$paporchap = "set link enable chap";
1382
			else
1383
				$paporchap = "set link enable pap";
1384

    
1385
			/* write mpd.conf */
1386
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1387
			if (!$fd) {
1388
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1389
				return 1;
1390
			}
1391
			$mpdconf = "\n\n";
1392
			$mpdconf .= "poes:\n";
1393

    
1394
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1395
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1396
			}
1397

    
1398
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1399

    
1400
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1401

    
1402
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1403
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1404
				} else {
1405
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1406
				}
1407

    
1408
				$mpdconf .=<<<EOD
1409

    
1410
poes{$pppoecfg['pppoeid']}{$i}:
1411
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1412
	{$isssue_ip_type}
1413
	load pppoe_standard
1414

    
1415
EOD;
1416
			}
1417

    
1418
			$mpdconf .=<<<EOD
1419

    
1420
pppoe_standard:
1421
	set bundle no multilink
1422
	set bundle enable compression
1423
	set auth max-logins 1
1424
	set iface up-script /usr/local/sbin/vpn-linkup
1425
	set iface down-script /usr/local/sbin/vpn-linkdown
1426
	set iface idle 0
1427
	set iface disable on-demand
1428
	set iface disable proxy-arp
1429
	set iface enable tcpmssfix
1430
	set iface mtu 1500
1431
	set link no pap chap
1432
	{$paporchap}
1433
	set link keep-alive 60 180
1434
	set ipcp yes vjcomp
1435
	set ipcp no vjcomp
1436
	set link max-redial -1
1437
	set link mtu 1492
1438
	set link mru 1492
1439
	set ccp yes mpp-e40
1440
	set ccp yes mpp-e128
1441
	set ccp yes mpp-stateless
1442
	set link latency 1
1443
	#set ipcp dns 10.10.1.3
1444
	#set bundle accept encryption
1445

    
1446
EOD;
1447

    
1448
			if (!empty($pppoecfg['dns1'])) {
1449
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1450
				if (!empty($pppoecfg['dns2']))
1451
					$mpdconf .= " " . $pppoecfg['dns2'];
1452
				$mpdconf .= "\n";
1453
			} elseif (isset ($config['dnsmasq']['enable'])) {
1454
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1455
				if ($syscfg['dnsserver'][0])
1456
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1457
				$mpdconf .= "\n";
1458
			} elseif (isset ($config['unbound']['enable'])) {
1459
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1460
				if ($syscfg['dnsserver'][0])
1461
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1462
				$mpdconf .= "\n";
1463
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1464
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1465
			}
1466

    
1467
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1468
				$radiusport = "";
1469
				$radiusacctport = "";
1470
				if (isset($pppoecfg['radius']['server']['port']))
1471
					$radiusport = $pppoecfg['radius']['server']['port'];
1472
				if (isset($pppoecfg['radius']['server']['acctport']))
1473
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1474
				$mpdconf .=<<<EOD
1475
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1476
	set radius retries 3
1477
	set radius timeout 10
1478
	set auth enable radius-auth
1479

    
1480
EOD;
1481

    
1482
				if (isset ($pppoecfg['radius']['accounting'])) {
1483
					$mpdconf .=<<<EOD
1484
	set auth enable radius-acct
1485

    
1486
EOD;
1487
				}
1488
			}
1489

    
1490
			fwrite($fd, $mpdconf);
1491
			fclose($fd);
1492
			unset($mpdconf);
1493

    
1494
			/* write mpd.links */
1495
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1496
			if (!$fd) {
1497
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1498
				return 1;
1499
			}
1500

    
1501
			$mpdlinks = "";
1502

    
1503
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1504
				$mpdlinks .=<<<EOD
1505

    
1506
poes{$pppoecfg['pppoeid']}{$i}:
1507
	set phys type pppoe
1508
	set pppoe iface {$pppoe_interface}
1509
	set pppoe service "*"
1510
	set pppoe disable originate
1511
	set pppoe enable incoming
1512

    
1513
EOD;
1514
			}
1515

    
1516
			fwrite($fd, $mpdlinks);
1517
			fclose($fd);
1518
			unset($mpdlinks);
1519

    
1520
			if ($pppoecfg['username']) {
1521
				/* write mpd.secret */
1522
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1523
				if (!$fd) {
1524
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1525
					return 1;
1526
				}
1527

    
1528
				$mpdsecret = "\n\n";
1529

    
1530
				if (!empty($pppoecfg['username'])) {
1531
					$item = explode(" ", $pppoecfg['username']);
1532
					foreach($item as $userdata) {
1533
						$data = explode(":", $userdata);
1534
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1535
					}
1536
				}
1537

    
1538
				fwrite($fd, $mpdsecret);
1539
				fclose($fd);
1540
				unset($mpdsecret);
1541
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1542
			}
1543

    
1544
			/* Check if previous instance is still up */
1545
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid"))
1546
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1547

    
1548
			/* Get support for netgraph(4) from the nic */
1549
			pfSense_ngctl_attach(".", $pppoe_interface);
1550
			/* fire up mpd */
1551
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1552

    
1553
			break;
1554
	}
1555

    
1556
	if (platform_booting())
1557
		echo gettext("done") . "\n";
1558

    
1559
	return 0;
1560
}
1561

    
1562
function vpn_l2tp_configure() {
1563
	global $config, $g;
1564

    
1565
	$syscfg = $config['system'];
1566
	$l2tpcfg = $config['l2tp'];
1567

    
1568
	/* create directory if it does not exist */
1569
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1570
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1571

    
1572
	if (platform_booting()) {
1573
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1574
			return 0;
1575

    
1576
		echo gettext("Configuring l2tp VPN service... ");
1577
	} else {
1578
		/* kill mpd */
1579
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1580

    
1581
		/* wait for process to die */
1582
		sleep(8);
1583

    
1584
	}
1585

    
1586
	/* make sure l2tp-vpn directory exists */
1587
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1588
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1589

    
1590
	switch ($l2tpcfg['mode']) {
1591

    
1592
		case 'server' :
1593
			if ($l2tpcfg['paporchap'] == "chap")
1594
				$paporchap = "set link enable chap";
1595
			else
1596
				$paporchap = "set link enable pap";
1597

    
1598
			/* write mpd.conf */
1599
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1600
			if (!$fd) {
1601
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1602
				return 1;
1603
			}
1604
			$mpdconf = "\n\n";
1605
			$mpdconf .=<<<EOD
1606
l2tps:
1607

    
1608
EOD;
1609

    
1610
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1611
				$mpdconf .= "	load l2tp{$i}\n";
1612
			}
1613

    
1614
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1615

    
1616
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1617

    
1618
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1619
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1620
				} else {
1621
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1622
				}
1623

    
1624
				$mpdconf .=<<<EOD
1625

    
1626
l2tp{$i}:
1627
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1628
	{$isssue_ip_type}
1629
	load l2tp_standard
1630

    
1631
EOD;
1632
			}
1633

    
1634
			$mpdconf .=<<<EOD
1635

    
1636
l2tp_standard:
1637
	set bundle disable multilink
1638
	set bundle enable compression
1639
	set bundle yes crypt-reqd
1640
	set ipcp yes vjcomp
1641
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1642
	set ccp yes mppc
1643
	set iface disable on-demand
1644
	set iface enable proxy-arp
1645
	set iface up-script /usr/local/sbin/vpn-linkup
1646
	set iface down-script /usr/local/sbin/vpn-linkdown
1647
	set link yes acfcomp protocomp
1648
	set link no pap chap
1649
	set link enable chap
1650
	set link keep-alive 10 180
1651

    
1652
EOD;
1653

    
1654
			if (is_ipaddr($l2tpcfg['wins'])) {
1655
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1656
			}
1657
			if (is_ipaddr($l2tpcfg['dns1'])) {
1658
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1659
				if (is_ipaddr($l2tpcfg['dns2']))
1660
					$mpdconf .= " " . $l2tpcfg['dns2'];
1661
				$mpdconf .= "\n";
1662
			} elseif (isset ($config['dnsmasq']['enable'])) {
1663
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1664
				if ($syscfg['dnsserver'][0])
1665
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1666
				$mpdconf .= "\n";
1667
			} elseif (isset ($config['unbound']['enable'])) {
1668
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1669
				if ($syscfg['dnsserver'][0])
1670
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1671
				$mpdconf .= "\n";
1672
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1673
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1674
			}
1675

    
1676
			if (isset ($l2tpcfg['radius']['enable'])) {
1677
				$mpdconf .=<<<EOD
1678
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1679
	set radius retries 3
1680
	set radius timeout 10
1681
	set auth enable radius-auth
1682

    
1683
EOD;
1684

    
1685
				if (isset ($l2tpcfg['radius']['accounting'])) {
1686
					$mpdconf .=<<<EOD
1687
	set auth enable radius-acct
1688

    
1689
EOD;
1690
				}
1691
			}
1692

    
1693
			fwrite($fd, $mpdconf);
1694
			fclose($fd);
1695
			unset($mpdconf);
1696

    
1697
			/* write mpd.links */
1698
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1699
			if (!$fd) {
1700
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1701
				return 1;
1702
			}
1703

    
1704
			$mpdlinks = "";
1705

    
1706
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1707
				$mpdlinks .=<<<EOD
1708

    
1709
l2tp{$i}:
1710
	set link type l2tp
1711
	set l2tp enable incoming
1712
	set l2tp disable originate
1713

    
1714
EOD;
1715
			if (!empty($l2tpcfg['secret']))
1716
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1717
			}
1718

    
1719
			fwrite($fd, $mpdlinks);
1720
			fclose($fd);
1721
			unset($mpdlinks);
1722

    
1723
			/* write mpd.secret */
1724
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1725
			if (!$fd) {
1726
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1727
				return 1;
1728
			}
1729

    
1730
			$mpdsecret = "\n\n";
1731

    
1732
			if (is_array($l2tpcfg['user'])) {
1733
				foreach ($l2tpcfg['user'] as $user)
1734
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1735
			}
1736

    
1737
			fwrite($fd, $mpdsecret);
1738
			fclose($fd);
1739
			unset($mpdsecret);
1740
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1741

    
1742
			vpn_netgraph_support();
1743

    
1744
			/* fire up mpd */
1745
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
1746

    
1747
			break;
1748

    
1749
		case 'redir' :
1750
			break;
1751
	}
1752

    
1753
	if (platform_booting())
1754
		echo "done\n";
1755

    
1756
	return 0;
1757
}
1758

    
1759
function vpn_ipsec_configure_preferoldsa() {
1760
	global $config;
1761
	if(isset($config['ipsec']['preferoldsa']))
1762
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1763
	else
1764
		set_single_sysctl("net.key.preferred_oldsa", "0");
1765
}
1766

    
1767
?>
(59-59/68)