Project

General

Profile

Download (53 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
	$syscfg = $config['system'];
109
	$ipseccfg = $config['ipsec'];
110
	if (!isset($ipseccfg['enable'])) {
111
		/* try to stop charon */
112
		mwexec("/usr/local/sbin/ipsec stop");
113
		/* Stop dynamic monitoring */
114
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
115

    
116
		/* wait for process to die */
117
		sleep(2);
118

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

    
123
		filter_configure();
124

    
125
		return 0;
126
	}
127

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

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

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

    
161
	if (platform_booting())
162
		echo gettext("Configuring IPsec VPN... ");
163

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
301
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
302
	if ($aggressive_mode_psk) {
303
		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.");
304
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE)
305
			$restart = true;
306
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
307
	} 
308

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

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

    
318
	unset($stronconf);
319

    
320
	$strongswan = <<<EOD
321

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

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

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

    
354
EOD;
355

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
475
	$pskconf = "";
476

    
477
	if (is_array($a_phase1) && count($a_phase1)) {
478
		foreach ($a_phase1 as $ph1ent) {
479

    
480
			if (isset($ph1ent['disabled']))
481
				continue;
482

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

    
487
				$ikeid = $ph1ent['ikeid'];
488
				$cert = lookup_cert($ph1ent['certref']);
489

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

    
495
				@chmod($certpath, 0600);
496

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

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

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

    
518
				if (empty($peerid_data))
519
					continue;
520

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

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

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

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

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

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

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

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

    
583
			$ep = ipsec_get_phase1_src($ph1ent);
584
			if (!$ep)
585
				continue;
586

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

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

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

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

    
672
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
673
			if ($myid_type != 'address')
674
				$myid_data = "{$myid_type}:{$myid_data}";
675

    
676
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
677
			$peerid_spec = '';
678
			if (!isset($ph1ent['mobile'])) {
679
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
680
				if ($peerid_type != 'address')
681
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
682
				else
683
					$peerid_spec = $peerid_data;
684
			}
685

    
686
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
687
				$ealgosp1 = '';
688
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
689
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
690
				if ($ealg_kl)
691
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
692
				else
693
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
694

    
695
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
696
				if (!empty($modp))
697
					$ealgosp1 .= "-{$modp}";
698

    
699
				$ealgosp1 .= "!";
700
			}
701

    
702
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
703
				if ($passive == "route")
704
					$dpdline = "dpdaction = restart";
705
				else
706
					$dpdline = "dpdaction = clear";
707
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
708
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
709
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
710
			} else
711
				$dpdline = "dpdaction = none";
712

    
713
			$ikelifeline = '';
714
			if ($ph1ent['lifetime'])
715
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
716

    
717
			$rightsourceip = NULL;
718
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
719
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
720

    
721
			$authentication = "";
722
			switch ($ph1ent['authentication_method']) {
723
			case 'eap-mschapv2':
724
				if (isset($ph1ent['mobile'])) {
725
					$authentication = "eap_identity=%any\n\t";
726
					$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
727
					if (!empty($ph1ent['certref']))
728
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
729
				}
730
				break;
731
			case 'eap-tls':
732
				if (isset($ph1ent['mobile'])) {
733
					$authentication = "eap_identity=%identity\n\t";
734
					$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
735
					if (!empty($ph1ent['certref']))
736
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
737
				} else {
738
					$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
739
					if (!empty($ph1ent['certref']))
740
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
741
				}
742
				break;
743
			case 'xauth_rsa_server':
744
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
745
				$authentication .= "\n\trightauth2 = xauth-generic";
746
				if (!empty($ph1ent['certref']))
747
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
748
				break;
749
			case 'xauth_psk_server':
750
				$authentication = "leftauth = psk\n\trightauth = psk";
751
				$authentication .= "\n\trightauth2 = xauth-generic";
752
				break;
753
			case 'pre_shared_key':
754
				$authentication = "leftauth = psk\n\trightauth = psk";
755
				break;
756
			case 'rsasig':
757
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
758
				if (!empty($ph1ent['certref']))
759
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
760
				break;
761
			case 'hybrid_rsa_server':
762
				$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
763
				$authentication .= "\n\trightauth2 = xauth";
764
				if (!empty($ph1ent['certref']))
765
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
766
				break;
767
			}
768

    
769
			$left_spec = $ep;
770

    
771
			if (isset($ph1ent['reauth_enable']))
772
				$reauth = "reauth = no";
773
			else
774
				$reauth = "reauth = yes";
775
			if (isset($ph1ent['rekey_enable']))
776
				$rekey = "rekey = no";
777
			else
778
				$rekey = "rekey = yes";
779

    
780
			if ($ph1ent['nat_traversal'] == 'off')
781
				$forceencaps = 'forceencaps = no';
782
			else if ($ph1ent['nat_traversal'] == 'force')
783
				$forceencaps = 'forceencaps = yes';
784
			else
785
				$forceencaps = 'forceencaps = no';
786
				
787
			if ($ph1ent['mobike'] == 'on')
788
				$mobike = 'mobike = yes';
789
			else
790
				$mobike = 'mobike = no';
791

    
792
			$ipseclifetime = 0;
793
			$rightsubnet_spec = array();
794
			$leftsubnet_spec = array();
795
			$reqids = array();
796
			$ealgoAHsp2arr = array();
797
			$ealgoESPsp2arr = array();
798
		if (is_array($a_phase2) && count($a_phase2)) {
799
			foreach ($a_phase2 as $ph2ent) {
800
				if ($ikeid != $ph2ent['ikeid'])
801
					continue;
802

    
803
				if (isset($ph2ent['disabled']))
804
					continue;
805

    
806
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
807
					continue;
808

    
809
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
810
					$tunneltype = "type = tunnel";
811

    
812
					$localid_type = $ph2ent['localid']['type'];
813
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
814

    
815
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
816
					if (($localid_type == "none" || $localid_type == "mobile")
817
					    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
818
						$left_spec = '%any';
819
					} else {
820
						if ($localid_type != "address") {
821
							$localid_type = "subnet";
822
						}
823
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
824
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
825
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
826
							continue;
827
						}
828
						if (!empty($ph2ent['natlocalid'])) {
829
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
830
							if ($ph2ent['natlocalid']['type'] != "address") {
831
								if (is_subnet($natleftsubnet_data))
832
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
833
							} else {
834
								if (is_ipaddr($natleftsubnet_data))
835
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
836
							}
837
							$natfilterrules = true;
838
						}
839
					}
840

    
841
					$leftsubnet_spec[] = $leftsubnet_data;
842

    
843
					if (!isset($ph2ent['mobile'])) {
844
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
845
						$rightsubnet_spec[] = $tmpsubnet;
846
					} else if (!empty($a_client['pool_address'])) {
847
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
848
					}
849
				} else {
850
					$tunneltype = "type = transport";
851

    
852
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
853
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
854
						$left_spec = "%any";
855
					} else {
856
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
857
						$leftsubnet_spec[] = $tmpsubnet;
858
					}
859

    
860
					if (!isset($ph2ent['mobile'])) {
861
						$rightsubnet_spec[] = $right_spec;
862
					}
863
				}
864

    
865
				if (isset($a_client['pfs_group']))
866
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
867

    
868
				if ($ph2ent['protocol'] == 'esp') {
869
					if (is_array($ph2ent['encryption-algorithm-option'])) {
870
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
871
							$ealg_id = $ealg['name'];
872
							$ealg_kl = $ealg['keylen'];
873

    
874
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
875
								if (empty($p2_ealgos) || !is_array($p2_ealgos))
876
									require("ipsec.inc");
877
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
878
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
879
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
880
								/* XXX: in some cases where include ordering is suspect these variables
881
								 * are somehow 0 and we enter this loop forever and timeout after 900
882
								 * seconds wrecking bootup */
883
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
884
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
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}{$keylen}-{$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}{$keylen}";
896
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
897
											if (!empty($modp))
898
												$tmpealgo .= "-{$modp}";
899
											$ealgoESPsp2arr[] = $tmpealgo;
900
										}
901
									}
902
								}
903
							} else {
904
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
905
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
906
										$halgo = str_replace('hmac_', '', $halgo);
907
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
908
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
909
										if (!empty($modp))
910
											$tmpealgo .= "-{$modp}";
911
										$ealgoESPsp2arr[] = $tmpealgo;
912
									}
913
								} else {
914
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
915
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
916
									if (!empty($modp))
917
										$tmpealgo .= "-{$modp}";
918
									$ealgoESPsp2arr[] = $tmpealgo;
919
								}
920
							}
921
						}
922
					}
923
				} else if ($ph2ent['protocol'] == 'ah') {
924
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
925
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
926
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
927
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
928
							if (!empty($modp))
929
								$tmpAHalgo = "-{$modp}";
930
							$ealgoAHsp2arr[] = $tmpAHalgo;
931
						}
932
					}
933
				}
934

    
935
				$reqids[] = $ph2ent['reqid'];
936

    
937
				if (!empty($ph2ent['lifetime'])) {
938
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
939
						$ipseclifetime = intval($ph2ent['lifetime']);
940
				}
941

    
942
			}
943
		}
944

    
945
			$ipsecconnect =<<<EOD
946
	fragmentation = yes
947
	keyexchange = {$keyexchange}
948
	{$reauth}
949
	{$forceencaps}
950
	{$mobike}
951
	{$rekey}
952
	installpolicy = yes
953
	{$tunneltype}
954
	{$dpdline}
955
	auto = {$passive}
956
	left = {$left_spec}
957
	right = {$right_spec}
958
	leftid = {$myid_data}
959

    
960
EOD;
961

    
962
			if (isset($config['ipsec']['compression'])) {
963
				$ipsecconnect .= "\tcompress = yes\n";
964
				$enablecompression = true;
965
			}
966
			if (!empty($ikelifeline))
967
				$ipsecconnect .= "\t{$ikelifeline}\n";
968
			if ($ipseclifetime > 0)
969
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
970
			if (!empty($rightsourceip))
971
				$ipsecconnect .= "{$rightsourceip}";
972
			if (!empty($ealgosp1))
973
				$ipsecconnect .= "\t{$ealgosp1}\n";
974
			if (!empty($ealgoAHsp2arr))
975
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
976
			if (!empty($ealgoESPsp2arr))
977
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
978
			if (!empty($authentication))
979
				$ipsecconnect .= "\t{$authentication}\n";
980
			if (!empty($peerid_spec))
981
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
982
			if ($keyexchange == 'ikev1')
983
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
984

    
985
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
986
				if (!empty($rightsubnet_spec)) {
987
					$ipsecfin = '';
988
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
989
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
990
						if (!empty($reqids[$idx]))
991
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
992
						$ipsecfin .= $ipsecconnect;
993
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
994
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
995
					}
996
				} else
997
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
998
			} else {
999
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1000
				if (!empty($reqids[$idx]))
1001
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1002
				$ipsecfin .= $ipsecconnect;
1003
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1004
					$tempsubnets = array();
1005
					foreach ($rightsubnet_spec as $rightsubnet)
1006
						$tempsubnets[$rightsubnet] = $rightsubnet;
1007
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1008
					unset($tempsubnets, $rightsubnet);
1009
				}
1010
				if (!empty($leftsubnet_spec)) {
1011
					$tempsubnets = array();
1012
					foreach ($leftsubnet_spec as $leftsubnet)
1013
						$tempsubnets[$leftsubnet] = $leftsubnet;
1014
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
1015
					unset($tempsubnets, $leftsubnet);
1016
				}
1017
			}
1018
			$ipsecconf .= $ipsecfin;
1019
			unset($ipsecfin);
1020

    
1021
		}
1022
	}
1023

    
1024
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1025
	unset($ipsecconf);
1026
	/* end ipsec.conf */
1027

    
1028
	if ($enablecompression === true)
1029
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1030
	else
1031
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1032

    
1033
	/* mange process */
1034
	if ($restart === true) {
1035
		mwexec("/usr/local/sbin/ipsec restart", false); 
1036
	} else {
1037
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1038
			/* Read secrets */
1039
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1040
			/* Update configuration changes */
1041
			mwexec("/usr/local/sbin/ipsec update", false);
1042
		} else {
1043
			mwexec("/usr/local/sbin/ipsec start", false); 
1044
		}
1045
	}
1046

    
1047
	if ($natfilterrules == true)
1048
		filter_configure();
1049
	/* start filterdns, if necessary */
1050
	if (count($filterdns_list) > 0) {
1051
		$interval = 60;
1052
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
1053
			$interval = $ipseccfg['dns-interval'];
1054

    
1055
		$hostnames = "";
1056
		array_unique($filterdns_list);
1057
		foreach ($filterdns_list as $hostname)
1058
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1059
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1060
		unset($hostnames);
1061

    
1062
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
1063
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1064
		else {
1065
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1066
		}
1067
	} else {
1068
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1069
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1070
	}
1071

    
1072
	if (platform_booting())
1073
		echo "done\n";
1074

    
1075
	return count($filterdns_list);
1076
}
1077

    
1078
/*
1079
 * Forcefully restart IPsec
1080
 * This is required for when dynamic interfaces reload
1081
 * For all other occasions the normal vpn_ipsec_configure()
1082
 * will gracefully reload the settings without restarting
1083
 */
1084
function vpn_ipsec_force_reload($interface = "") {
1085
	global $g, $config;
1086

    
1087
	$ipseccfg = $config['ipsec'];
1088

    
1089
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1090
		$found = false;
1091
		foreach ($ipseccfg['phase1'] as $ipsec) {
1092
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1093
				$found = true;
1094
				break;
1095
			}
1096
		}
1097
		if (!$found) {
1098
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1099
			return;
1100
		}
1101
	}
1102

    
1103
	/* if ipsec is enabled, start up again */
1104
	if (isset($ipseccfg['enable'])) {
1105
		log_error(gettext("Forcefully reloading IPsec"));
1106
		vpn_ipsec_configure();
1107
	}
1108
}
1109

    
1110
/* master setup for vpn (mpd) */
1111
function vpn_setup() {
1112
	global $g;
1113

    
1114
	if ($g['platform'] == 'jail')
1115
		return;
1116

    
1117
	/* start pptpd */
1118
	vpn_pptpd_configure();
1119

    
1120
	/* start pppoe server */
1121
	vpn_pppoes_configure();
1122

    
1123
	/* setup l2tp */
1124
	vpn_l2tp_configure();
1125
}
1126

    
1127
function vpn_netgraph_support() {
1128
	$iflist = get_configured_interface_list();
1129
	foreach ($iflist as $iface) {
1130
		$realif = get_real_interface($iface);
1131
		/* Get support for netgraph(4) from the nic */
1132
		$ifinfo = pfSense_get_interface_addresses($realif);
1133
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1134
			pfSense_ngctl_attach(".", $realif);
1135
	}
1136
}
1137

    
1138
function vpn_pptpd_configure() {
1139
	global $config, $g;
1140

    
1141
	$syscfg = $config['system'];
1142
	$pptpdcfg = $config['pptpd'];
1143

    
1144
	if (platform_booting()) {
1145
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1146
			return 0;
1147

    
1148
		if (platform_booting(true))
1149
			echo gettext("Configuring PPTP VPN service... ");
1150
	} else {
1151
		/* kill mpd */
1152
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1153

    
1154
		/* wait for process to die */
1155
		sleep(3);
1156

    
1157
		if (is_process_running("mpd -b")) {
1158
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1159
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1160
		}
1161

    
1162
		/* remove mpd.conf, if it exists */
1163
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1164
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1165
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1166
	}
1167

    
1168
	if (empty($pptpdcfg['n_pptp_units'])) {
1169
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1170
		return;
1171
	}
1172

    
1173
	/* make sure pptp-vpn directory exists */
1174
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1175
		mkdir("{$g['varetc_path']}/pptp-vpn");
1176

    
1177
	switch ($pptpdcfg['mode']) {
1178
		case 'server' :
1179
			/* write mpd.conf */
1180
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1181
			if (!$fd) {
1182
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1183
				return 1;
1184
			}
1185

    
1186
			$mpdconf = <<<EOD
1187
pptps:
1188

    
1189
EOD;
1190

    
1191
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1192
				$mpdconf .= "	load pt{$i}\n";
1193
			}
1194

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

    
1197
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1198

    
1199
				$mpdconf .= <<<EOD
1200

    
1201
pt{$i}:
1202
	new -i pptpd{$i} pt{$i} pt{$i}
1203
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1204
	load pts
1205

    
1206
EOD;
1207
			}
1208

    
1209
			$mpdconf .=<<<EOD
1210

    
1211
pts:
1212
	set iface disable on-demand
1213
	set iface enable proxy-arp
1214
	set iface enable tcpmssfix
1215
	set iface idle 1800
1216
	set iface up-script /usr/local/sbin/vpn-linkup
1217
	set iface down-script /usr/local/sbin/vpn-linkdown
1218
	set bundle enable multilink
1219
	set bundle enable crypt-reqd
1220
	set link yes acfcomp protocomp
1221
	set link no pap chap
1222
	set link enable chap-msv2
1223
	set link mtu 1460
1224
	set link keep-alive 10 60
1225
	set ipcp yes vjcomp
1226
	set bundle enable compression
1227
	set ccp yes mppc
1228
	set ccp yes mpp-e128
1229
	set ccp yes mpp-stateless
1230

    
1231
EOD;
1232

    
1233
			if (!isset ($pptpdcfg['req128'])) {
1234
				$mpdconf .=<<<EOD
1235
	set ccp yes mpp-e40
1236
	set ccp yes mpp-e56
1237

    
1238
EOD;
1239
			}
1240

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

    
1244
			if (!empty($pptpdcfg['dns1'])) {
1245
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1246
				if (!empty($pptpdcfg['dns2']))
1247
					$mpdconf .= " " . $pptpdcfg['dns2'];
1248
				$mpdconf .= "\n";
1249
			} elseif (isset ($config['dnsmasq']['enable'])) {
1250
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1251
				if ($syscfg['dnsserver'][0])
1252
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1253
				$mpdconf .= "\n";
1254
			} elseif (isset($config['unbound']['enable'])) {
1255
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1256
				if ($syscfg['dnsserver'][0])
1257
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1258
				$mpdconf .= "\n";
1259
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1260
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1261
			}
1262

    
1263
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1264
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1265
				$acctport = $authport + 1;
1266
				$mpdconf .=<<<EOD
1267
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1268

    
1269
EOD;
1270
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1271
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1272
				$acctport = $authport + 1;
1273
				$mpdconf .=<<<EOD
1274
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1275

    
1276
EOD;
1277
			}
1278
			$mpdconf .=<<<EOD
1279
	set radius retries 3
1280
	set radius timeout 10
1281
	set auth enable radius-auth
1282

    
1283
EOD;
1284

    
1285
				if (isset ($pptpdcfg['radius']['accounting'])) {
1286
					$mpdconf .=<<<EOD
1287
	set auth enable radius-acct
1288
	set radius acct-update 300
1289

    
1290
EOD;
1291
				}
1292
			}
1293

    
1294
			fwrite($fd, $mpdconf);
1295
			fclose($fd);
1296
			unset($mpdconf);
1297

    
1298
			/* write mpd.links */
1299
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1300
			if (!$fd) {
1301
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1302
				return 1;
1303
			}
1304

    
1305
			$mpdlinks = "";
1306

    
1307
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1308
				$mpdlinks .=<<<EOD
1309

    
1310
pt{$i}:
1311
	set link type pptp
1312
	set pptp enable incoming
1313
	set pptp disable originate
1314
	set pptp disable windowing
1315

    
1316
EOD;
1317
			}
1318

    
1319
			fwrite($fd, $mpdlinks);
1320
			fclose($fd);
1321
			unset($mpdlinks);
1322

    
1323
			/* write mpd.secret */
1324
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1325
			if (!$fd) {
1326
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1327
				return 1;
1328
			}
1329

    
1330
			$mpdsecret = "";
1331

    
1332
			if (is_array($pptpdcfg['user'])) {
1333
				foreach ($pptpdcfg['user'] as $user) {
1334
					$pass = str_replace('\\', '\\\\', $user['password']);
1335
					$pass = str_replace('"', '\"', $pass);
1336
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1337
				}
1338
			}
1339

    
1340
			fwrite($fd, $mpdsecret);
1341
			fclose($fd);
1342
			unset($mpdsecret);
1343
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1344

    
1345
			vpn_netgraph_support();
1346

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

    
1350
			break;
1351

    
1352
		case 'redir' :
1353
			break;
1354
	}
1355

    
1356
	if (platform_booting())
1357
		echo "done\n";
1358

    
1359
	return 0;
1360
}
1361

    
1362
function vpn_pppoes_configure() {
1363
	global $config;
1364

    
1365
	if (is_array($config['pppoes']['pppoe'])) {
1366
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1367
			vpn_pppoe_configure($pppoe);
1368
	}
1369
}
1370

    
1371
function vpn_pppoe_configure(&$pppoecfg) {
1372
	global $config, $g;
1373

    
1374
	$syscfg = $config['system'];
1375

    
1376
	/* create directory if it does not exist */
1377
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1378
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1379

    
1380
	if (platform_booting()) {
1381
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1382
			return 0;
1383

    
1384
		echo gettext("Configuring PPPoE Server service... ");
1385
	} else {
1386
		/* kill mpd */
1387
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1388

    
1389
		/* wait for process to die */
1390
		sleep(2);
1391

    
1392
	}
1393

    
1394
	switch ($pppoecfg['mode']) {
1395

    
1396
		case 'server' :
1397

    
1398
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1399

    
1400
			if ($pppoecfg['paporchap'] == "chap")
1401
				$paporchap = "set link enable chap";
1402
			else
1403
				$paporchap = "set link enable pap";
1404

    
1405
			/* write mpd.conf */
1406
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1407
			if (!$fd) {
1408
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1409
				return 1;
1410
			}
1411
			$mpdconf = "\n\n";
1412
			$mpdconf .= "poes:\n";
1413

    
1414
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1415
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1416
			}
1417

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

    
1420
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1421

    
1422
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1423
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1424
				} else {
1425
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1426
				}
1427

    
1428
				$mpdconf .=<<<EOD
1429

    
1430
poes{$pppoecfg['pppoeid']}{$i}:
1431
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1432
	{$isssue_ip_type}
1433
	load pppoe_standard
1434

    
1435
EOD;
1436
			}
1437

    
1438
			$mpdconf .=<<<EOD
1439

    
1440
pppoe_standard:
1441
	set bundle no multilink
1442
	set bundle enable compression
1443
	set auth max-logins 1
1444
	set iface up-script /usr/local/sbin/vpn-linkup
1445
	set iface down-script /usr/local/sbin/vpn-linkdown
1446
	set iface idle 0
1447
	set iface disable on-demand
1448
	set iface disable proxy-arp
1449
	set iface enable tcpmssfix
1450
	set iface mtu 1500
1451
	set link no pap chap
1452
	{$paporchap}
1453
	set link keep-alive 60 180
1454
	set ipcp yes vjcomp
1455
	set ipcp no vjcomp
1456
	set link max-redial -1
1457
	set link mtu 1492
1458
	set link mru 1492
1459
	set ccp yes mpp-e40
1460
	set ccp yes mpp-e128
1461
	set ccp yes mpp-stateless
1462
	set link latency 1
1463
	#set ipcp dns 10.10.1.3
1464
	#set bundle accept encryption
1465

    
1466
EOD;
1467

    
1468
			if (!empty($pppoecfg['dns1'])) {
1469
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1470
				if (!empty($pppoecfg['dns2']))
1471
					$mpdconf .= " " . $pppoecfg['dns2'];
1472
				$mpdconf .= "\n";
1473
			} elseif (isset ($config['dnsmasq']['enable'])) {
1474
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1475
				if ($syscfg['dnsserver'][0])
1476
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1477
				$mpdconf .= "\n";
1478
			} elseif (isset ($config['unbound']['enable'])) {
1479
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1480
				if ($syscfg['dnsserver'][0])
1481
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1482
				$mpdconf .= "\n";
1483
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1484
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1485
			}
1486

    
1487
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1488
				$radiusport = "";
1489
				$radiusacctport = "";
1490
				if (isset($pppoecfg['radius']['server']['port']))
1491
					$radiusport = $pppoecfg['radius']['server']['port'];
1492
				if (isset($pppoecfg['radius']['server']['acctport']))
1493
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1494
				$mpdconf .=<<<EOD
1495
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1496
	set radius retries 3
1497
	set radius timeout 10
1498
	set auth enable radius-auth
1499

    
1500
EOD;
1501

    
1502
				if (isset ($pppoecfg['radius']['accounting'])) {
1503
					$mpdconf .=<<<EOD
1504
	set auth enable radius-acct
1505

    
1506
EOD;
1507
				}
1508
			}
1509

    
1510
			fwrite($fd, $mpdconf);
1511
			fclose($fd);
1512
			unset($mpdconf);
1513

    
1514
			/* write mpd.links */
1515
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1516
			if (!$fd) {
1517
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1518
				return 1;
1519
			}
1520

    
1521
			$mpdlinks = "";
1522

    
1523
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1524
				$mpdlinks .=<<<EOD
1525

    
1526
poes{$pppoecfg['pppoeid']}{$i}:
1527
	set phys type pppoe
1528
	set pppoe iface {$pppoe_interface}
1529
	set pppoe service "*"
1530
	set pppoe disable originate
1531
	set pppoe enable incoming
1532

    
1533
EOD;
1534
			}
1535

    
1536
			fwrite($fd, $mpdlinks);
1537
			fclose($fd);
1538
			unset($mpdlinks);
1539

    
1540
			if ($pppoecfg['username']) {
1541
				/* write mpd.secret */
1542
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1543
				if (!$fd) {
1544
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1545
					return 1;
1546
				}
1547

    
1548
				$mpdsecret = "\n\n";
1549

    
1550
				if (!empty($pppoecfg['username'])) {
1551
					$item = explode(" ", $pppoecfg['username']);
1552
					foreach($item as $userdata) {
1553
						$data = explode(":", $userdata);
1554
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1555
					}
1556
				}
1557

    
1558
				fwrite($fd, $mpdsecret);
1559
				fclose($fd);
1560
				unset($mpdsecret);
1561
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1562
			}
1563

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

    
1568
			/* Get support for netgraph(4) from the nic */
1569
			pfSense_ngctl_attach(".", $pppoe_interface);
1570
			/* fire up mpd */
1571
			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");
1572

    
1573
			break;
1574
	}
1575

    
1576
	if (platform_booting())
1577
		echo gettext("done") . "\n";
1578

    
1579
	return 0;
1580
}
1581

    
1582
function vpn_l2tp_configure() {
1583
	global $config, $g;
1584

    
1585
	$syscfg = $config['system'];
1586
	$l2tpcfg = $config['l2tp'];
1587

    
1588
	/* create directory if it does not exist */
1589
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1590
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1591

    
1592
	if (platform_booting()) {
1593
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1594
			return 0;
1595

    
1596
		echo gettext("Configuring l2tp VPN service... ");
1597
	} else {
1598
		/* kill mpd */
1599
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1600

    
1601
		/* wait for process to die */
1602
		sleep(8);
1603

    
1604
	}
1605

    
1606
	/* make sure l2tp-vpn directory exists */
1607
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1608
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1609

    
1610
	switch ($l2tpcfg['mode']) {
1611

    
1612
		case 'server' :
1613
			if ($l2tpcfg['paporchap'] == "chap")
1614
				$paporchap = "set link enable chap";
1615
			else
1616
				$paporchap = "set link enable pap";
1617

    
1618
			/* write mpd.conf */
1619
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1620
			if (!$fd) {
1621
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1622
				return 1;
1623
			}
1624
			$mpdconf = "\n\n";
1625
			$mpdconf .=<<<EOD
1626
l2tps:
1627

    
1628
EOD;
1629

    
1630
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1631
				$mpdconf .= "	load l2tp{$i}\n";
1632
			}
1633

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

    
1636
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1637

    
1638
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1639
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1640
				} else {
1641
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1642
				}
1643

    
1644
				$mpdconf .=<<<EOD
1645

    
1646
l2tp{$i}:
1647
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1648
	{$isssue_ip_type}
1649
	load l2tp_standard
1650

    
1651
EOD;
1652
			}
1653

    
1654
			$mpdconf .=<<<EOD
1655

    
1656
l2tp_standard:
1657
	set bundle disable multilink
1658
	set bundle enable compression
1659
	set bundle yes crypt-reqd
1660
	set ipcp yes vjcomp
1661
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1662
	set ccp yes mppc
1663
	set iface disable on-demand
1664
	set iface enable proxy-arp
1665
	set iface up-script /usr/local/sbin/vpn-linkup
1666
	set iface down-script /usr/local/sbin/vpn-linkdown
1667
	set link yes acfcomp protocomp
1668
	set link no pap chap
1669
	{$paporchap}
1670
	set link keep-alive 10 180
1671

    
1672
EOD;
1673

    
1674
			if (is_ipaddr($l2tpcfg['wins'])) {
1675
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1676
			}
1677
			if (is_ipaddr($l2tpcfg['dns1'])) {
1678
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1679
				if (is_ipaddr($l2tpcfg['dns2']))
1680
					$mpdconf .= " " . $l2tpcfg['dns2'];
1681
				$mpdconf .= "\n";
1682
			} elseif (isset ($config['dnsmasq']['enable'])) {
1683
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1684
				if ($syscfg['dnsserver'][0])
1685
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1686
				$mpdconf .= "\n";
1687
			} elseif (isset ($config['unbound']['enable'])) {
1688
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1689
				if ($syscfg['dnsserver'][0])
1690
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1691
				$mpdconf .= "\n";
1692
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1693
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1694
			}
1695

    
1696
			if (isset ($l2tpcfg['radius']['enable'])) {
1697
				$mpdconf .=<<<EOD
1698
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1699
	set radius retries 3
1700
	set radius timeout 10
1701
	set auth enable radius-auth
1702

    
1703
EOD;
1704

    
1705
				if (isset ($l2tpcfg['radius']['accounting'])) {
1706
					$mpdconf .=<<<EOD
1707
	set auth enable radius-acct
1708

    
1709
EOD;
1710
				}
1711
			}
1712

    
1713
			fwrite($fd, $mpdconf);
1714
			fclose($fd);
1715
			unset($mpdconf);
1716

    
1717
			/* write mpd.links */
1718
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1719
			if (!$fd) {
1720
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1721
				return 1;
1722
			}
1723

    
1724
			$mpdlinks = "";
1725

    
1726
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1727
				$mpdlinks .=<<<EOD
1728

    
1729
l2tp{$i}:
1730
	set link type l2tp
1731
	set l2tp enable incoming
1732
	set l2tp disable originate
1733

    
1734
EOD;
1735
			if (!empty($l2tpcfg['secret']))
1736
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1737
			}
1738

    
1739
			fwrite($fd, $mpdlinks);
1740
			fclose($fd);
1741
			unset($mpdlinks);
1742

    
1743
			/* write mpd.secret */
1744
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1745
			if (!$fd) {
1746
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1747
				return 1;
1748
			}
1749

    
1750
			$mpdsecret = "\n\n";
1751

    
1752
			if (is_array($l2tpcfg['user'])) {
1753
				foreach ($l2tpcfg['user'] as $user)
1754
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1755
			}
1756

    
1757
			fwrite($fd, $mpdsecret);
1758
			fclose($fd);
1759
			unset($mpdsecret);
1760
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1761

    
1762
			vpn_netgraph_support();
1763

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

    
1767
			break;
1768

    
1769
		case 'redir' :
1770
			break;
1771
	}
1772

    
1773
	if (platform_booting())
1774
		echo "done\n";
1775

    
1776
	return 0;
1777
}
1778

    
1779
?>
(59-59/68)