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
require_once("filter.inc");
45

    
46
function vpn_ipsec_configure_loglevels($forconfig = false) {
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
	}
59
	if ($forconfig) {
60
		return implode(',', $cfgtext);
61
	}
62
}
63

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

    
67
	$convertion = "";
68
	switch ($index) {
69
		case '1':
70
			$convertion = "modp768";
71
			break;
72
		case '2':
73
			$convertion = "modp1024";
74
			break;
75
		case '5':
76
			$convertion = "modp1536";
77
			break;
78
		case '14':
79
			$convertion = "modp2048";
80
			break;
81
		case '15':
82
			$convertion = "modp3072";
83
			break;
84
		case '16':
85
			$convertion = "modp4096";
86
			break;
87
		case '17':
88
			$convertion = "modp6144";
89
			break;
90
		case '18':
91
			$convertion = "modp8192";
92
			break;
93
		case '19':
94
			$convertion = "ecp256";
95
			break;
96
		case '20':
97
			$convertion = "ecp384";
98
			break;
99
		case '21':
100
			$convertion = "ecp521";
101
			break;
102
		case '22':
103
			$convertion = "modp1024s160";
104
			break;
105
		case '23':
106
			$convertion = "modp2048s224";
107
			break;
108
		case '24':
109
			$convertion = "modp2048s256";
110
			break;
111
		case '28':
112
			$convertion = "ecp256bp";
113
			break;
114
		case '29':
115
			$convertion = "ecp384bp";
116
			break;
117
		case '30':
118
			$convertion = "ecp512bp";
119
			break;
120
	}
121

    
122
	return $convertion;
123
}
124

    
125
function vpn_ipsec_configure($restart = false) {
126
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
127

    
128
	/* get the automatic ping_hosts.sh ready */
129
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
130
	touch("{$g['vardb_path']}/ipsecpinghosts");
131

    
132
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
133
	filter_configure();
134

    
135
	$syscfg = $config['system'];
136
	$ipseccfg = $config['ipsec'];
137
	if (!isset($ipseccfg['enable'])) {
138
		/* try to stop charon */
139
		mwexec("/usr/local/sbin/ipsec stop");
140
		/* Stop dynamic monitoring */
141
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
142

    
143
		/* wait for process to die */
144
		sleep(2);
145

    
146
		/* disallow IPSEC, it is off */
147
		mwexec("/sbin/ifconfig enc0 down");
148
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
149

    
150
		return 0;
151
	}
152

    
153
	$a_phase1 = $config['ipsec']['phase1'];
154
	$a_phase2 = $config['ipsec']['phase2'];
155
	$a_client = $config['ipsec']['client'];
156

    
157
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
158
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
159
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
160
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
161

    
162
	mwexec("/sbin/ifconfig enc0 up");
163
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
164
	if (php_uname('m') != "amd64") {
165
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
166
	}
167

    
168
	/* needed for config files */
169
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
170
		mkdir("{$g['varetc_path']}/ipsec");
171
	}
172
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
173
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
174
	}
175
	if (!is_dir($capath)) {
176
		mkdir($capath);
177
	}
178
	if (!is_dir($keypath)) {
179
		mkdir($keypath);
180
	}
181
	if (!is_dir($crlpath)) {
182
		mkdir($crlpath);
183
	}
184
	if (!is_dir($certpath)) {
185
		mkdir($certpath);
186
	}
187
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
188
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
189
	}
190
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
191
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
192
	}
193
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
194
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
195
	}
196
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
197
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
198
	}
199

    
200

    
201
	if (platform_booting()) {
202
		echo gettext("Configuring IPsec VPN... ");
203
	}
204

    
205
	/* fastforwarding is not compatible with ipsec tunnels */
206
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
207

    
208
	/* resolve all local, peer addresses and setup pings */
209
	$ipmap = array();
210
	$rgmap = array();
211
	$filterdns_list = array();
212
	$listeniflist = array();
213
	$aggressive_mode_psk = false;
214
	unset($iflist);
215
	$ifacesuse = array();
216
	if (is_array($a_phase1) && count($a_phase1)) {
217

    
218
		$ipsecpinghosts = "";
219
		/* step through each phase1 entry */
220
		foreach ($a_phase1 as $ph1ent) {
221
			if (isset($ph1ent['disabled'])) {
222
				continue;
223
			}
224

    
225
			if (strpos($ph1ent['interface'], '_vip')) {
226
				$vpninterface = explode('_vip', $ph1ent['interface']);
227
				$ifacesuse[] = get_real_interface($vpninterface[0]);
228
			} else {
229
				$vpninterface = get_failover_interface($ph1ent['interface']);
230
				if (strpos($vpninterface, '_vip')) {
231
					$vpninterface = explode('_vip', $vpninterface);
232
					$ifacesuse[] = get_real_interface($vpninterface[0]);
233
				} elseif (!empty($vpninterface)) {
234
					$ifacesuse[] = $vpninterface;
235
				}
236
			}
237

    
238
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
239
				$aggressive_mode_psk = true;
240
			}
241

    
242
			$ikeid = $ph1ent['ikeid'];
243
			$listeniflist = get_real_interface($a_phase1['interface']);
244

    
245
			$ep = ipsec_get_phase1_src($ph1ent);
246
			if (!is_ipaddr($ep)) {
247
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
248
				continue;
249
			}
250

    
251
			if (!in_array($ep, $ipmap)) {
252
				$ipmap[] = $ep;
253
			}
254

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

    
258
			if (isset ($ph1ent['mobile'])) {
259
				continue;
260
			}
261

    
262
			$rg = $ph1ent['remote-gateway'];
263

    
264
			if (!is_ipaddr($rg)) {
265
				$filterdns_list[] = "{$rg}";
266
				add_hostname_to_watch($rg);
267
				if (!platform_booting()) {
268
					$rg = resolve_retry($rg);
269
				}
270
				if (!is_ipaddr($rg)) {
271
					continue;
272
				}
273
			}
274
			if (array_search($rg, $rgmap)) {
275
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
276
				continue;
277
			}
278
			$rgmap[$ph1ent['remote-gateway']] = $rg;
279

    
280
			if (is_array($a_phase2)) {
281
				/* step through each phase2 entry */
282
				foreach ($a_phase2 as $ph2ent) {
283
					if (isset($ph2ent['disabled'])) {
284
						continue;
285
					}
286

    
287
					if ($ikeid != $ph2ent['ikeid']) {
288
						continue;
289
					}
290

    
291
					/* add an ipsec pinghosts entry */
292
					if ($ph2ent['pinghost']) {
293
						if (!is_array($iflist)) {
294
							$iflist = get_configured_interface_list();
295
						}
296
						$srcip = null;
297
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
298
						if (is_ipaddrv6($ph2ent['pinghost'])) {
299
							foreach ($iflist as $ifent => $ifname) {
300
								$interface_ip = get_interface_ipv6($ifent);
301
								if (!is_ipaddrv6($interface_ip)) {
302
									continue;
303
								}
304
								if (ip_in_subnet($interface_ip, $local_subnet)) {
305
									$srcip = $interface_ip;
306
									break;
307
								}
308
							}
309
						} else {
310
							foreach ($iflist as $ifent => $ifname) {
311
								$interface_ip = get_interface_ip($ifent);
312
								if (!is_ipaddrv4($interface_ip)) {
313
									continue;
314
								}
315
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
316
									$srcip = $interface_ip;
317
									break;
318
								}
319
							}
320
						}
321
						/* if no valid src IP was found in configured interfaces, try the vips */
322
						if (is_null($srcip)) {
323
							$viplist = get_configured_vips_list();
324
							foreach ($viplist as $vip) {
325
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
326
									$srcip = $vip['ipaddr'];
327
									break;
328
								}
329
							}
330
						}
331
						$dstip = $ph2ent['pinghost'];
332
						if (is_ipaddrv6($dstip)) {
333
							$family = "inet6";
334
						} else {
335
							$family = "inet";
336
						}
337
						if (is_ipaddr($srcip)) {
338
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
339
						}
340
					}
341
				}
342
			}
343
		}
344
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
345
		unset($ipsecpinghosts);
346
	}
347
	unset($iflist);
348

    
349
	$accept_unencrypted = "";
350
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
351
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
352
	}
353

    
354
	$stronconf = '';
355
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
356
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
357
	}
358

    
359
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
360
	if ($aggressive_mode_psk) {
361
		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.");
362
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
363
			$restart = true;
364
		}
365
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
366
	}
367

    
368
	$unity_enabled = 'yes';
369
	if (isset($config['ipsec']['unityplugin'])) {
370
		$unity_enabled = 'no';
371
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
372
			conf_mount_rw();
373
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
374
			conf_mount_ro();
375
		}
376
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
377
		conf_mount_rw();
378
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
379
		conf_mount_ro();
380
	}
381

    
382
	$makebeforebreak = '';
383
	if (isset($config['ipsec']['makebeforebreak'])) {
384
		$makebeforebreak = 'make_before_break = yes';
385
	}
386

    
387
	if (isset($config['ipsec']['enableinterfacesuse'])) {
388
		if (!empty($ifacesuse)) {
389
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
390
		} else {
391
			$ifacesuse = '';
392
		}
393
	} else {
394
		$ifacesuse = '';
395
	}
396

    
397
	unset($stronconf);
398

    
399
	$strongswan = <<<EOD
400

    
401
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
402
starter {
403
load_warning = no
404
}
405

    
406
charon {
407
# number of worker threads in charon
408
threads = 16
409
ikesa_table_size = 32
410
ikesa_table_segments = 4
411
init_limit_half_open = 1000
412
install_routes = no
413
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
414
{$accept_unencrypted}
415
cisco_unity = {$unity_enabled}
416
{$ifacesuse}
417
{$makebeforebreak}
418

    
419
# And two loggers using syslog. The subsections define the facility to log
420
# to, currently one of: daemon, auth.
421
syslog {
422
	identifier = charon
423
	# default level to the LOG_DAEMON facility
424
	daemon {
425
		ike_name = yes
426
	}
427
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
428
	auth {
429
		default = -1
430
		ike = 1
431
		ike_name = yes
432
	}
433
}
434

    
435
EOD;
436

    
437
	$strongswan .= "\tplugins {\n";
438

    
439
	$a_servers = auth_get_authserver_list();
440
	foreach ($a_servers as $id => $pconfig) {
441
		if ($id == $config['ipsec']['client']['user_source'] && $pconfig['type'] == "radius") {
442
			$strongswan .= <<<EOD
443
		eap-radius {
444
			class_group = yes
445
			eap_start = no
446
			servers {
447
				primary {
448
					address = {$pconfig['host']}
449
					secret = {$pconfig['radius_secret']}
450
					auth_port = {$pconfig['radius_auth_port']}
451
					acct_port = {$pconfig['radius_acct_port']}
452
				}
453
			}
454
		}
455

    
456
EOD;
457
			break;
458
		}
459
	}
460

    
461
	if (is_array($a_client) && isset($a_client['enable'])) {
462
		$strongswan .= "\t\tattr {\n";
463
		if ($a_client['pool_address'] && $a_client['pool_netbits']) {
464
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
465
		}
466

    
467
		$cfgservers = array();
468
		if (!empty($a_client['dns_server1'])) {
469
			$cfgservers[] = $a_client['dns_server1'];
470
		}
471
		if (!empty($a_client['dns_server2'])) {
472
			$cfgservers[] = $a_client['dns_server2'];
473
		}
474
		if (!empty($a_client['dns_server3'])) {
475
			$cfgservers[] = $a_client['dns_server3'];
476
		}
477
		if (!empty($a_client['dns_server4'])) {
478
			$cfgservers[] = $a_client['dns_server4'];
479
		}
480

    
481
		if (!empty($cfgservers)) {
482
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
483
		}
484
		unset($cfgservers);
485
		$cfgservers = array();
486
		if (!empty($a_client['wins_server1'])) {
487
			$cfgservers[] = $a_client['wins_server1'];
488
		}
489
		if (!empty($a_client['wins_server2'])) {
490
			$cfgservers[] = $a_client['wins_server2'];
491
		}
492
		if (!empty($cfgservers)) {
493
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
494
		}
495
		unset($cfgservers);
496

    
497
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
498
			$net_list = '';
499
			foreach ($a_phase2 as $ph2ent) {
500
				if (isset($ph2ent['disabled'])) {
501
					continue;
502
				}
503

    
504
				if (!isset($ph2ent['mobile'])) {
505
					continue;
506
				}
507

    
508
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
509

    
510
				if (!empty($net_list)) {
511
					$net_list .= ",";
512
				}
513
				$net_list .= $localid;
514
			}
515

    
516
			if (!empty($net_list)) {
517
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
518
				unset($net_list);
519
			}
520
		}
521

    
522
		if (!empty($a_client['dns_domain'])) {
523
			$strongswan .= "\t\t\t# Search domain and default domain\n";
524
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
525
			if (empty($a_client['dns_split'])) {
526
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
527
			}
528
			$strongswan .= "\n";
529
		}
530

    
531
		if (!empty($a_client['dns_split'])) {
532
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
533
		}
534

    
535
		if (!empty($a_client['login_banner'])) {
536
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
537
		}
538

    
539
		if (isset($a_client['save_passwd'])) {
540
			$strongswan .= "\t\t\t28673 = 1\n";
541
		}
542

    
543
		if ($a_client['pfs_group']) {
544
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
545
		}
546
		$strongswan .= "\t\t}\n";
547

    
548
		if ($a_client['user_source'] != "none") {
549
			$strongswan .= "\t\txauth-generic {\n";
550
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
551
			$strongswan .= "\t\t\tauthcfg = ";
552
			$firstsed = 0;
553
			$authcfgs = explode(",", $a_client['user_source']);
554
			foreach ($authcfgs as $authcfg) {
555
				if ($firstsed > 0) {
556
					$strongswan .= ",";
557
				}
558
				if ($authcfg == "system") {
559
					$authcfg = "Local Database";
560
				}
561
				$strongswan .= $authcfg;
562
				$firstsed = 1;
563
			}
564
			$strongswan .= "\n";
565
			$strongswan .= "\t\t}\n";
566
		}
567
	}
568

    
569
	$strongswan .= "\t}\n}\n";
570
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
571
	unset($strongswan);
572

    
573
	/* generate CA certificates files */
574
	if (is_array($config['ca']) && count($config['ca'])) {
575
		foreach ($config['ca'] as $ca) {
576
			if (!isset($ca['crt'])) {
577
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
578
				continue;
579
			}
580
			$cert = base64_decode($ca['crt']);
581
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
582
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
583
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
584
				continue;
585
			}
586
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
587
			if (!@file_put_contents($fname, $cert)) {
588
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
589
				continue;
590
			}
591
			unset($cert);
592
		}
593
	}
594

    
595
	/* write out CRL files */
596
	if (is_array($config['crl']) && count($config['crl'])) {
597
		foreach ($config['crl'] as $crl) {
598
			if (!isset($crl['text'])) {
599
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
600
				continue;
601
			}
602
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
603
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
604
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
605
				continue;
606
			}
607
		}
608
	}
609

    
610
	$pskconf = "";
611

    
612
	if (is_array($a_phase1) && count($a_phase1)) {
613
		foreach ($a_phase1 as $ph1ent) {
614

    
615
			if (isset($ph1ent['disabled'])) {
616
				continue;
617
			}
618

    
619
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
620
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
621
				$certline = '';
622

    
623
				$ikeid = $ph1ent['ikeid'];
624
				$cert = lookup_cert($ph1ent['certref']);
625

    
626
				if (!$cert) {
627
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
628
					continue;
629
				}
630

    
631
				@chmod($certpath, 0600);
632

    
633
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
634
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
635
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
636
					continue;
637
				}
638
				@chmod($ph1keyfile, 0600);
639

    
640
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
641
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
642
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
643
					@unlink($ph1keyfile);
644
					continue;
645
				}
646
				@chmod($ph1certfile, 0600);
647

    
648
				/* XXX" Traffic selectors? */
649
				$pskconf .= " : RSA {$ph1keyfile}\n";
650
			} else {
651
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
652
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
653

    
654
				$myid = trim($myid_data);
655

    
656
				if (empty($peerid_data)) {
657
					continue;
658
				}
659

    
660
				if ($myid_type == 'fqdn' && !empty($myid)) {
661
					$myid = "@{$myid}";
662
				}
663

    
664
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
665

    
666
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
667

    
668
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
669
					$peerid = "@{$peerid}";
670
				}
671

    
672
				if (!empty($ph1ent['pre-shared-key'])) {
673
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
674
				}
675
			}
676
		}
677
	}
678

    
679
	/* Add user PSKs */
680
	if (is_array($config['system']) && is_array($config['system']['user'])) {
681
		foreach ($config['system']['user'] as $user) {
682
			if (!empty($user['ipsecpsk'])) {
683
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
684
			}
685
		}
686
		unset($user);
687
	}
688

    
689
	/* add PSKs for mobile clients */
690
	if (is_array($ipseccfg['mobilekey'])) {
691
		foreach ($ipseccfg['mobilekey'] as $key) {
692
			if ($key['ident'] == "allusers") {
693
				$key['ident'] = '%any';
694
			}
695
			if (empty($key['type'])) {
696
				$key['type'] = 'PSK';
697
			}
698
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
699
		}
700
		unset($key);
701
	}
702

    
703
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
704
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
705
	unset($pskconf);
706

    
707
	$uniqueids = 'yes';
708
	if (!empty($config['ipsec']['uniqueids'])) {
709
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
710
			$uniqueids = $config['ipsec']['uniqueids'];
711
		}
712
	}
713
	$natfilterrules = false;
714
	/* begin ipsec.conf */
715
	$ipsecconf = "";
716
	$enablecompression = false;
717
	if (is_array($a_phase1) && count($a_phase1)) {
718

    
719
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
720
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
721
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
722

    
723
		if (isset($config['ipsec']['strictcrlpolicy'])) {
724
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
725
		}
726

    
727
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
728
			if ($config['interfaces']['lan']) {
729
				$lanip = get_interface_ip("lan");
730
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
731
					$lansn = get_interface_subnet("lan");
732
					$lansa = gen_subnet($lanip, $lansn);
733
					$ipsecconf .= <<<EOD
734

    
735
conn bypasslan
736
	leftsubnet = {$lansa}/{$lansn}
737
	rightsubnet = {$lansa}/{$lansn}
738
	authby = never
739
	type = passthrough
740
	auto = route
741

    
742
EOD;
743
				}
744
			}
745
		}
746

    
747
		foreach ($a_phase1 as $ph1ent) {
748
			if (isset($ph1ent['disabled'])) {
749
				continue;
750
			}
751

    
752
			if ($ph1ent['mode'] == "aggressive") {
753
				$aggressive = "yes";
754
			} else {
755
				$aggressive = "no";
756
			}
757

    
758
			$ep = ipsec_get_phase1_src($ph1ent);
759
			if (!$ep) {
760
				continue;
761
			}
762

    
763
			$ikeid = $ph1ent['ikeid'];
764
			$keyexchange = "ikev1";
765
			$passive = "route";
766
			if (!empty($ph1ent['iketype'])) {
767
				if ($ph1ent['iketype'] == "ikev2") {
768
					$keyexchange = "ikev2";
769
					//$passive = "start";
770
				}
771
			}
772

    
773
			if (isset($ph1ent['mobile'])) {
774
				$right_spec = "%any";
775
				$passive = 'add';
776
			} else {
777
				if (isset($ph1ent['responderonly'])) {
778
					$passive = 'add';
779
				}
780

    
781
				$right_spec = $ph1ent['remote-gateway'];
782
				if (is_ipaddr($right_spec)) {
783
					$sourcehost = $right_spec;
784
				} else {
785
					$sourcehost = $rgmap['remote-gateway'];
786
				}
787

    
788
				if ($ph1ent['protocol'] == 'inet') {
789
					if (strpos($ph1ent['interface'], '_vip')) {
790
						$vpninterface = explode('_vip', $ph1ent['interface']);
791
						$ifacesuse = get_real_interface($vpninterface[0]);
792
						$vpninterface = $vpninterface[0];
793
					} else {
794
						$ifacesuse = get_failover_interface($ph1ent['interface']);
795
						if (strpos($ifacesuse, '_vip')) {
796
							$vpninterface = explode('_vip', $ifacesuse);
797
							$ifacesuse = get_real_interface($vpninterface[0]);
798
							$vpninterface = $vpninterface[0];
799
						} else {
800
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
801
						}
802
					}
803

    
804
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
805
						$gatewayip = get_interface_gateway($vpninterface);
806
						$interfaceip = get_interface_ip($vpninterface);
807
						$subnet_bits = get_interface_subnet($vpninterface);
808
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
809
						/* if the remote gateway is in the local subnet, then don't add a route */
810
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
811
							if (is_ipaddrv4($gatewayip)) {
812
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
813
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
814
							}
815
						}
816
					}
817
				} else if ($ph1ent['protocol'] == 'inet6') {
818
					if (strpos($ph1ent['interface'], '_vip')) {
819
						$vpninterface = explode('_vip', $ph1ent['interface']);
820
						$ifacesuse = get_real_interface($vpninterface[0]);
821
						$vpninterface = $vpninterface[0];
822
					} else {
823
						$ifacesuse = get_failover_interface($ph1ent['interface']);
824
						if (strpos($ifacesuse, '_vip')) {
825
							$vpninterface = explode('_vip', $ifacesuse);
826
							$ifacesuse = get_real_interface($vpninterface[0]);
827
							$vpninterface = $vpninterface[0];
828
						} else {
829
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
830
						}
831
					}
832

    
833
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
834
						$gatewayip = get_interface_gateway_v6($vpninterface);
835
						$interfaceip = get_interface_ipv6($vpninterface);
836
						$subnet_bits = get_interface_subnetv6($vpninterface);
837
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
838
						/* if the remote gateway is in the local subnet, then don't add a route */
839
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
840
							if (is_ipaddrv6($gatewayip)) {
841
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
842
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
843
							}
844
						}
845
					}
846
				}
847
			}
848

    
849
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
850
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
851
				$myid_data = "{$myid_type}:{$myid_data}";
852
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
853
				if ($myid_data[0] == '#') {
854
				/* asn1dn needs double quotes */
855
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
856
				} else {
857
					$myid_data = "\"{$myid_data}\"";
858
				}
859
			}
860
			$leftid = '';
861
			if (!empty($myid_data)) {
862
				$leftid = "leftid = {$myid_data}";
863
			}
864

    
865
			$peerid_spec = '';
866
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
867
				// Only specify peer ID if we are not dealing with mobile PSK
868
			} else {
869
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
870
				if ($peerid_type == 'any') {
871
					$peerid_spec = '';
872
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
873
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
874
				} elseif ($peerid_type == "asn1dn") {
875
					/* asn1dn needs double quotes */
876
					if ($peerid_data[0] == '#') {
877
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
878
					} elseif (!empty($peerid_data)) {
879
						$peerid_spec = "\"{$peerid_data}\"";
880
					}
881
				} else {
882
					$peerid_spec = $peerid_data;
883
				}
884
			}
885

    
886
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
887
				$ealgosp1 = '';
888
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
889
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
890
				if ($ealg_kl) {
891
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
892
				} else {
893
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
894
				}
895

    
896
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
897
				if (!empty($modp)) {
898
					$ealgosp1 .= "-{$modp}";
899
				}
900

    
901
				$ealgosp1 .= "!";
902
			}
903

    
904
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
905
				if ($passive == "route") {
906
					$dpdline = "dpdaction = restart";
907
				} else {
908
					$dpdline = "dpdaction = clear";
909
				}
910
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
911
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
912
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
913
			} else {
914
				$dpdline = "dpdaction = none";
915
			}
916

    
917
			$ikelifeline = '';
918
			if ($ph1ent['lifetime']) {
919
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
920
			}
921

    
922
			$rightsourceip = NULL;
923
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
924
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
925
			}
926

    
927
			$authentication = "";
928
			switch ($ph1ent['authentication_method']) {
929
				case 'eap-mschapv2':
930
					if (isset($ph1ent['mobile'])) {
931
						$authentication = "eap_identity=%any\n\t";
932
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
933
						if (!empty($ph1ent['certref'])) {
934
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
935
						}
936
					}
937
					break;
938
				case 'eap-tls':
939
					if (isset($ph1ent['mobile'])) {
940
						$authentication = "eap_identity=%identity\n\t";
941
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
942
						if (!empty($ph1ent['certref'])) {
943
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
944
						}
945
					} else {
946
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
947
						if (!empty($ph1ent['certref'])) {
948
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
949
						}
950
					}
951
					break;
952
				case 'eap-radius':
953
					if (isset($ph1ent['mobile'])) {
954
						$authentication = "eap_identity=%identity\n\t";
955
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
956
						if (!empty($ph1ent['certref'])) {
957
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
958
						}
959
					} else {
960
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
961
						if (!empty($ph1ent['certref'])) {
962
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
963
						}
964
					}
965
					break;
966
				case 'xauth_rsa_server':
967
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
968
					$authentication .= "\n\trightauth2 = xauth-generic";
969
					if (!empty($ph1ent['certref'])) {
970
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
971
					}
972
					break;
973
				case 'xauth_psk_server':
974
					$authentication = "leftauth = psk\n\trightauth = psk";
975
					$authentication .= "\n\trightauth2 = xauth-generic";
976
					break;
977
				case 'pre_shared_key':
978
					$authentication = "leftauth = psk\n\trightauth = psk";
979
					break;
980
				case 'rsasig':
981
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
982
					if (!empty($ph1ent['certref'])) {
983
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
984
					}
985
					break;
986
				case 'hybrid_rsa_server':
987
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
988
					$authentication .= "\n\trightauth2 = xauth";
989
					if (!empty($ph1ent['certref'])) {
990
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
991
					}
992
					break;
993
			}
994

    
995
			$left_spec = $ep;
996

    
997
			if (isset($ph1ent['reauth_enable'])) {
998
				$reauth = "reauth = no";
999
			} else {
1000
				$reauth = "reauth = yes";
1001
			}
1002
			if (isset($ph1ent['rekey_enable'])) {
1003
				$rekey = "rekey = no";
1004
			} else {
1005
				$rekey = "rekey = yes";
1006
			}
1007

    
1008
			if ($ph1ent['nat_traversal'] == 'off') {
1009
				$forceencaps = 'forceencaps = no';
1010
			} else if ($ph1ent['nat_traversal'] == 'force') {
1011
				$forceencaps = 'forceencaps = yes';
1012
			} else {
1013
				$forceencaps = 'forceencaps = no';
1014
			}
1015

    
1016
			if ($ph1ent['mobike'] == 'on') {
1017
				$mobike = 'mobike = yes';
1018
			} else {
1019
				$mobike = 'mobike = no';
1020
			}
1021

    
1022
			$ipseclifetime = 0;
1023
			$rightsubnet_spec = array();
1024
			$leftsubnet_spec = array();
1025
			$reqids = array();
1026
			$ealgoAHsp2arr = array();
1027
			$ealgoESPsp2arr = array();
1028
		if (is_array($a_phase2) && count($a_phase2)) {
1029
			foreach ($a_phase2 as $ph2ent) {
1030
				if ($ikeid != $ph2ent['ikeid']) {
1031
					continue;
1032
				}
1033

    
1034
				if (isset($ph2ent['disabled'])) {
1035
					continue;
1036
				}
1037

    
1038
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1039
					continue;
1040
				}
1041

    
1042
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1043
					$tunneltype = "type = tunnel";
1044

    
1045
					$localid_type = $ph2ent['localid']['type'];
1046
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1047

    
1048
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1049
					if (($localid_type == "none" || $localid_type == "mobile") &&
1050
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1051
						$left_spec = '%any';
1052
					} else {
1053
						if ($localid_type != "address") {
1054
							$localid_type = "subnet";
1055
						}
1056
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1057
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1058
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1059
							continue;
1060
						}
1061
						if (!empty($ph2ent['natlocalid'])) {
1062
							$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1063
							if ($ph2ent['natlocalid']['type'] != "address") {
1064
								if (is_subnet($natleftsubnet_data)) {
1065
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1066
								}
1067
							} else {
1068
								if (is_ipaddr($natleftsubnet_data)) {
1069
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1070
								}
1071
							}
1072
							$natfilterrules = true;
1073
						}
1074
					}
1075

    
1076
					$leftsubnet_spec[] = $leftsubnet_data;
1077

    
1078
					if (!isset($ph2ent['mobile'])) {
1079
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1080
						$rightsubnet_spec[] = $tmpsubnet;
1081
					} else if (!empty($a_client['pool_address'])) {
1082
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1083
					}
1084
				} else {
1085
					$tunneltype = "type = transport";
1086

    
1087
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1088
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
1089
						$left_spec = "%any";
1090
					} else {
1091
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1092
						$leftsubnet_spec[] = $tmpsubnet;
1093
					}
1094

    
1095
					if (!isset($ph2ent['mobile'])) {
1096
						$rightsubnet_spec[] = $right_spec;
1097
					}
1098
				}
1099

    
1100
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1101
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1102
				}
1103

    
1104
				if ($ph2ent['protocol'] == 'esp') {
1105
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1106
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1107
							$ealg_id = $ealg['name'];
1108
							$ealg_kl = $ealg['keylen'];
1109

    
1110
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
1111
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1112
									require("ipsec.inc");
1113
								}
1114
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1115
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1116
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1117
								/* XXX: in some cases where include ordering is suspect these variables
1118
								 * are somehow 0 and we enter this loop forever and timeout after 900
1119
								 * seconds wrecking bootup */
1120
								if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1121
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1122
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1123
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1124
												$halgo = str_replace('hmac_', '', $halgo);
1125
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1126
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1127
												if (!empty($modp)) {
1128
													$tmpealgo .= "-{$modp}";
1129
												}
1130
												$ealgoESPsp2arr[] = $tmpealgo;
1131
											}
1132
										} else {
1133
											$tmpealgo = "{$ealg_id}{$keylen}";
1134
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1135
											if (!empty($modp)) {
1136
												$tmpealgo .= "-{$modp}";
1137
											}
1138
											$ealgoESPsp2arr[] = $tmpealgo;
1139
										}
1140
									}
1141
								}
1142
							} else {
1143
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1144
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1145
										$halgo = str_replace('hmac_', '', $halgo);
1146
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1147
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1148
										if (!empty($modp)) {
1149
											$tmpealgo .= "-{$modp}";
1150
										}
1151
										$ealgoESPsp2arr[] = $tmpealgo;
1152
									}
1153
								} else {
1154
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1155
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1156
									if (!empty($modp)) {
1157
										$tmpealgo .= "-{$modp}";
1158
									}
1159
									$ealgoESPsp2arr[] = $tmpealgo;
1160
								}
1161
							}
1162
						}
1163
					}
1164
				} else if ($ph2ent['protocol'] == 'ah') {
1165
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1166
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1167
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1168
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1169
							if (!empty($modp)) {
1170
								$tmpAHalgo = "-{$modp}";
1171
							}
1172
							$ealgoAHsp2arr[] = $tmpAHalgo;
1173
						}
1174
					}
1175
				}
1176

    
1177
				$reqids[] = $ph2ent['reqid'];
1178

    
1179
				if (!empty($ph2ent['lifetime'])) {
1180
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1181
						$ipseclifetime = intval($ph2ent['lifetime']);
1182
					}
1183
				}
1184

    
1185
			}
1186
		}
1187

    
1188
			$ipsecconnect =<<<EOD
1189
	fragmentation = yes
1190
	keyexchange = {$keyexchange}
1191
	{$reauth}
1192
	{$forceencaps}
1193
	{$mobike}
1194
	{$rekey}
1195
	installpolicy = yes
1196
	{$tunneltype}
1197
	{$dpdline}
1198
	auto = {$passive}
1199
	left = {$left_spec}
1200
	right = {$right_spec}
1201
	{$leftid}
1202

    
1203
EOD;
1204

    
1205
			if (isset($config['ipsec']['compression'])) {
1206
				$ipsecconnect .= "\tcompress = yes\n";
1207
				$enablecompression = true;
1208
			}
1209
			if (!empty($ikelifeline)) {
1210
				$ipsecconnect .= "\t{$ikelifeline}\n";
1211
			}
1212
			if ($ipseclifetime > 0) {
1213
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1214
			}
1215
			if (!empty($rightsourceip)) {
1216
				$ipsecconnect .= "{$rightsourceip}";
1217
			}
1218
			if (!empty($ealgosp1)) {
1219
				$ipsecconnect .= "\t{$ealgosp1}\n";
1220
			}
1221
			if (!empty($ealgoAHsp2arr)) {
1222
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1223
			}
1224
			if (!empty($ealgoESPsp2arr)) {
1225
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1226
			}
1227
			if (!empty($authentication)) {
1228
				$ipsecconnect .= "\t{$authentication}\n";
1229
			}
1230
			if (!empty($peerid_spec)) {
1231
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1232
			}
1233
			if ($keyexchange == 'ikev1') {
1234
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1235
			}
1236

    
1237
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1238
				if (!empty($rightsubnet_spec)) {
1239
					$ipsecfin = '';
1240
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1241
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1242
						//if (!empty($reqids[$idx])) {
1243
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1244
						//}
1245
						$ipsecfin .= $ipsecconnect;
1246
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1247
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1248
					}
1249
				} else {
1250
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1251
				}
1252
			} else {
1253
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1254
				//if (!empty($reqids[$idx])) {
1255
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1256
				//}
1257
				$ipsecfin .= $ipsecconnect;
1258
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1259
					$tempsubnets = array();
1260
					foreach ($rightsubnet_spec as $rightsubnet) {
1261
						$tempsubnets[$rightsubnet] = $rightsubnet;
1262
					}
1263
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1264
					unset($tempsubnets, $rightsubnet);
1265
				}
1266
				if (!empty($leftsubnet_spec)) {
1267
					$tempsubnets = array();
1268
					foreach ($leftsubnet_spec as $leftsubnet) {
1269
						$tempsubnets[$leftsubnet] = $leftsubnet;
1270
					}
1271
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1272
					unset($tempsubnets, $leftsubnet);
1273
				}
1274
			}
1275
			$ipsecconf .= $ipsecfin;
1276
			unset($ipsecfin);
1277
		}
1278
	}
1279

    
1280
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1281
	unset($ipsecconf);
1282
	/* end ipsec.conf */
1283

    
1284
	if ($enablecompression === true) {
1285
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1286
	} else {
1287
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1288
	}
1289

    
1290
	/* manage process */
1291
	if ($restart === true) {
1292
		mwexec("/usr/local/sbin/ipsec restart", false);
1293
	} else {
1294
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1295
			/* Update configuration changes */
1296
			/* Read secrets */
1297
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1298
			mwexec("/usr/local/sbin/ipsec reload", false);
1299
		} else {
1300
			mwexec("/usr/local/sbin/ipsec start", false);
1301
		}
1302
	}
1303

    
1304
	if ($natfilterrules == true) {
1305
		filter_configure();
1306
	}
1307
	/* start filterdns, if necessary */
1308
	if (count($filterdns_list) > 0) {
1309
		$interval = 60;
1310
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1311
			$interval = $ipseccfg['dns-interval'];
1312
		}
1313

    
1314
		$hostnames = "";
1315
		array_unique($filterdns_list);
1316
		foreach ($filterdns_list as $hostname) {
1317
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1318
		}
1319
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1320
		unset($hostnames);
1321

    
1322
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1323
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1324
		} else {
1325
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1326
		}
1327
	} else {
1328
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1329
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1330
	}
1331

    
1332
	if (platform_booting()) {
1333
		echo "done\n";
1334
	}
1335

    
1336
	return count($filterdns_list);
1337
}
1338

    
1339
/*
1340
 * Forcefully restart IPsec
1341
 * This is required for when dynamic interfaces reload
1342
 * For all other occasions the normal vpn_ipsec_configure()
1343
 * will gracefully reload the settings without restarting
1344
 */
1345
function vpn_ipsec_force_reload($interface = "") {
1346
	global $g, $config;
1347

    
1348
	$ipseccfg = $config['ipsec'];
1349

    
1350
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1351
		$found = false;
1352
		foreach ($ipseccfg['phase1'] as $ipsec) {
1353
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1354
				$found = true;
1355
				break;
1356
			}
1357
		}
1358
		if (!$found) {
1359
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1360
			return;
1361
		}
1362
	}
1363

    
1364
	/* if ipsec is enabled, start up again */
1365
	if (isset($ipseccfg['enable'])) {
1366
		log_error(gettext("Forcefully reloading IPsec"));
1367
		vpn_ipsec_configure();
1368
	}
1369
}
1370

    
1371
/* master setup for vpn (mpd) */
1372
function vpn_setup() {
1373
	/* start pppoe server */
1374
	vpn_pppoes_configure();
1375

    
1376
	/* setup l2tp */
1377
	vpn_l2tp_configure();
1378
}
1379

    
1380
function vpn_netgraph_support() {
1381
	$iflist = get_configured_interface_list();
1382
	foreach ($iflist as $iface) {
1383
		$realif = get_real_interface($iface);
1384
		/* Get support for netgraph(4) from the nic */
1385
		$ifinfo = pfSense_get_interface_addresses($realif);
1386
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1387
			pfSense_ngctl_attach(".", $realif);
1388
		}
1389
	}
1390
}
1391

    
1392
function vpn_pppoes_configure() {
1393
	global $config;
1394

    
1395
	if (is_array($config['pppoes']['pppoe'])) {
1396
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1397
			vpn_pppoe_configure($pppoe);
1398
		}
1399
	}
1400
}
1401

    
1402
function vpn_pppoe_configure(&$pppoecfg) {
1403
	global $config, $g;
1404

    
1405
	$syscfg = $config['system'];
1406

    
1407
	/* create directory if it does not exist */
1408
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1409
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1410
	}
1411

    
1412
	if (platform_booting()) {
1413
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1414
			return 0;
1415
		}
1416

    
1417
		echo gettext("Configuring PPPoE Server service... ");
1418
	} else {
1419
		/* kill mpd */
1420
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1421

    
1422
		/* wait for process to die */
1423
		sleep(2);
1424

    
1425
	}
1426

    
1427
	switch ($pppoecfg['mode']) {
1428

    
1429
		case 'server':
1430

    
1431
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1432

    
1433
			if ($pppoecfg['paporchap'] == "chap") {
1434
				$paporchap = "set link enable chap";
1435
			} else {
1436
				$paporchap = "set link enable pap";
1437
			}
1438

    
1439
			/* write mpd.conf */
1440
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1441
			if (!$fd) {
1442
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1443
				return 1;
1444
			}
1445
			$mpdconf = "\n\n";
1446
			$mpdconf .= "poes:\n";
1447

    
1448
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1449
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1450
			}
1451

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

    
1454
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1455

    
1456
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1457
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1458
				} else {
1459
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1460
				}
1461

    
1462
				$mpdconf .=<<<EOD
1463

    
1464
poes{$pppoecfg['pppoeid']}{$i}:
1465
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1466
	{$issue_ip_type}
1467
	load pppoe_standard
1468

    
1469
EOD;
1470
			}
1471

    
1472
			$mpdconf .=<<<EOD
1473

    
1474
pppoe_standard:
1475
	set bundle no multilink
1476
	set bundle enable compression
1477
	set auth max-logins 1
1478
	set iface up-script /usr/local/sbin/vpn-linkup
1479
	set iface down-script /usr/local/sbin/vpn-linkdown
1480
	set iface idle 0
1481
	set iface disable on-demand
1482
	set iface disable proxy-arp
1483
	set iface enable tcpmssfix
1484
	set iface mtu 1500
1485
	set link no pap chap
1486
	{$paporchap}
1487
	set link keep-alive 60 180
1488
	set ipcp yes vjcomp
1489
	set ipcp no vjcomp
1490
	set link max-redial -1
1491
	set link mtu 1492
1492
	set link mru 1492
1493
	set ccp yes mpp-e40
1494
	set ccp yes mpp-e128
1495
	set ccp yes mpp-stateless
1496
	set link latency 1
1497
	#set ipcp dns 10.10.1.3
1498
	#set bundle accept encryption
1499

    
1500
EOD;
1501

    
1502
			if (!empty($pppoecfg['dns1'])) {
1503
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1504
				if (!empty($pppoecfg['dns2'])) {
1505
					$mpdconf .= " " . $pppoecfg['dns2'];
1506
				}
1507
				$mpdconf .= "\n";
1508
			} elseif (isset ($config['dnsmasq']['enable'])) {
1509
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1510
				if ($syscfg['dnsserver'][0]) {
1511
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1512
				}
1513
				$mpdconf .= "\n";
1514
			} elseif (isset ($config['unbound']['enable'])) {
1515
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1516
				if ($syscfg['dnsserver'][0]) {
1517
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1518
				}
1519
				$mpdconf .= "\n";
1520
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1521
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1522
			}
1523

    
1524
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1525
				$radiusport = "";
1526
				$radiusacctport = "";
1527
				if (isset($pppoecfg['radius']['server']['port'])) {
1528
					$radiusport = $pppoecfg['radius']['server']['port'];
1529
				}
1530
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1531
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1532
				}
1533
				$mpdconf .=<<<EOD
1534
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1535
	set radius retries 3
1536
	set radius timeout 10
1537
	set auth enable radius-auth
1538

    
1539
EOD;
1540

    
1541
				if (isset ($pppoecfg['radius']['accounting'])) {
1542
					$mpdconf .=<<<EOD
1543
	set auth enable radius-acct
1544

    
1545
EOD;
1546
				}
1547
			}
1548

    
1549
			fwrite($fd, $mpdconf);
1550
			fclose($fd);
1551
			unset($mpdconf);
1552

    
1553
			/* write mpd.links */
1554
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1555
			if (!$fd) {
1556
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1557
				return 1;
1558
			}
1559

    
1560
			$mpdlinks = "";
1561

    
1562
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1563
				$mpdlinks .=<<<EOD
1564

    
1565
poes{$pppoecfg['pppoeid']}{$i}:
1566
	set phys type pppoe
1567
	set pppoe iface {$pppoe_interface}
1568
	set pppoe service "*"
1569
	set pppoe disable originate
1570
	set pppoe enable incoming
1571

    
1572
EOD;
1573
			}
1574

    
1575
			fwrite($fd, $mpdlinks);
1576
			fclose($fd);
1577
			unset($mpdlinks);
1578

    
1579
			if ($pppoecfg['username']) {
1580
				/* write mpd.secret */
1581
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1582
				if (!$fd) {
1583
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1584
					return 1;
1585
				}
1586

    
1587
				$mpdsecret = "\n\n";
1588

    
1589
				if (!empty($pppoecfg['username'])) {
1590
					$item = explode(" ", $pppoecfg['username']);
1591
					foreach ($item as $userdata) {
1592
						$data = explode(":", $userdata);
1593
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1594
					}
1595
				}
1596

    
1597
				fwrite($fd, $mpdsecret);
1598
				fclose($fd);
1599
				unset($mpdsecret);
1600
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1601
			}
1602

    
1603
			/* Check if previous instance is still up */
1604
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1605
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1606
			}
1607

    
1608
			/* Get support for netgraph(4) from the nic */
1609
			pfSense_ngctl_attach(".", $pppoe_interface);
1610
			/* fire up mpd */
1611
			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");
1612

    
1613
			break;
1614
	}
1615

    
1616
	if (platform_booting()) {
1617
		echo gettext("done") . "\n";
1618
	}
1619

    
1620
	return 0;
1621
}
1622

    
1623
function vpn_l2tp_configure() {
1624
	global $config, $g;
1625

    
1626
	$syscfg = $config['system'];
1627
	$l2tpcfg = $config['l2tp'];
1628

    
1629
	/* create directory if it does not exist */
1630
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1631
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1632
	}
1633

    
1634
	if (platform_booting()) {
1635
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1636
			return 0;
1637
		}
1638

    
1639
		echo gettext("Configuring l2tp VPN service... ");
1640
	} else {
1641
		/* kill mpd */
1642
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1643

    
1644
		/* wait for process to die */
1645
		sleep(8);
1646

    
1647
	}
1648

    
1649
	/* make sure l2tp-vpn directory exists */
1650
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1651
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1652
	}
1653

    
1654
	switch ($l2tpcfg['mode']) {
1655

    
1656
		case 'server':
1657
			$l2tp_listen="";
1658
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1659
			if (is_ipaddrv4($ipaddr)) {
1660
				$l2tp_listen="set l2tp self $ipaddr";
1661
			}
1662

    
1663
			switch ($l2tpcfg['paporchap']) {
1664
				case 'chap':
1665
					$paporchap = "set link enable chap";
1666
					break;
1667
				case 'chap-msv2':
1668
					$paporchap = "set link enable chap-msv2";
1669
					break;
1670
				default:
1671
					$paporchap = "set link enable pap";
1672
					break;
1673
			}
1674

    
1675
			/* write mpd.conf */
1676
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1677
			if (!$fd) {
1678
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1679
				return 1;
1680
			}
1681
			$mpdconf = "\n\n";
1682
			$mpdconf .=<<<EOD
1683
l2tps:
1684

    
1685
EOD;
1686

    
1687
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1688
				$mpdconf .= "	load l2tp{$i}\n";
1689
			}
1690

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

    
1693
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1694

    
1695
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1696
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1697
				} else {
1698
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1699
				}
1700

    
1701
				$mpdconf .=<<<EOD
1702

    
1703
l2tp{$i}:
1704
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1705
	{$issue_ip_type}
1706
	load l2tp_standard
1707

    
1708
EOD;
1709
			}
1710

    
1711
			$mpdconf .=<<<EOD
1712

    
1713
l2tp_standard:
1714
	set bundle disable multilink
1715
	set bundle enable compression
1716
	set bundle yes crypt-reqd
1717
	set ipcp yes vjcomp
1718
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1719
	set ccp yes mppc
1720
	set iface disable on-demand
1721
	set iface enable proxy-arp
1722
	set iface up-script /usr/local/sbin/vpn-linkup
1723
	set iface down-script /usr/local/sbin/vpn-linkdown
1724
	set link yes acfcomp protocomp
1725
	set link no pap chap
1726
	{$paporchap}
1727
	{$l2tp_listen}
1728
	set link keep-alive 10 180
1729

    
1730
EOD;
1731

    
1732
			if (is_ipaddr($l2tpcfg['wins'])) {
1733
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1734
			}
1735
			if (is_ipaddr($l2tpcfg['dns1'])) {
1736
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1737
				if (is_ipaddr($l2tpcfg['dns2'])) {
1738
					$mpdconf .= " " . $l2tpcfg['dns2'];
1739
				}
1740
				$mpdconf .= "\n";
1741
			} elseif (isset ($config['dnsmasq']['enable'])) {
1742
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1743
				if ($syscfg['dnsserver'][0]) {
1744
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1745
				}
1746
				$mpdconf .= "\n";
1747
			} elseif (isset ($config['unbound']['enable'])) {
1748
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1749
				if ($syscfg['dnsserver'][0]) {
1750
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1751
				}
1752
				$mpdconf .= "\n";
1753
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1754
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1755
			}
1756

    
1757
			if (isset ($l2tpcfg['radius']['enable'])) {
1758
				$mpdconf .=<<<EOD
1759
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1760
	set radius retries 3
1761
	set radius timeout 10
1762
	set auth enable radius-auth
1763

    
1764
EOD;
1765

    
1766
				if (isset ($l2tpcfg['radius']['accounting'])) {
1767
					$mpdconf .=<<<EOD
1768
	set auth enable radius-acct
1769

    
1770
EOD;
1771
				}
1772
			}
1773

    
1774
			fwrite($fd, $mpdconf);
1775
			fclose($fd);
1776
			unset($mpdconf);
1777

    
1778
			/* write mpd.links */
1779
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1780
			if (!$fd) {
1781
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1782
				return 1;
1783
			}
1784

    
1785
			$mpdlinks = "";
1786

    
1787
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1788
				$mpdlinks .=<<<EOD
1789

    
1790
l2tp{$i}:
1791
	set link type l2tp
1792
	set l2tp enable incoming
1793
	set l2tp disable originate
1794

    
1795
EOD;
1796
				if (!empty($l2tpcfg['secret'])) {
1797
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1798
				}
1799
			}
1800

    
1801
			fwrite($fd, $mpdlinks);
1802
			fclose($fd);
1803
			unset($mpdlinks);
1804

    
1805
			/* write mpd.secret */
1806
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1807
			if (!$fd) {
1808
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1809
				return 1;
1810
			}
1811

    
1812
			$mpdsecret = "\n\n";
1813

    
1814
			if (is_array($l2tpcfg['user'])) {
1815
				foreach ($l2tpcfg['user'] as $user) {
1816
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1817
				}
1818
			}
1819

    
1820
			fwrite($fd, $mpdsecret);
1821
			fclose($fd);
1822
			unset($mpdsecret);
1823
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1824

    
1825
			vpn_netgraph_support();
1826

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

    
1830
			break;
1831

    
1832
		case 'redir':
1833
			break;
1834
	}
1835

    
1836
	if (platform_booting()) {
1837
		echo "done\n";
1838
	}
1839

    
1840
	return 0;
1841
}
1842

    
1843
?>
(59-59/68)