Project

General

Profile

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

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

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

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

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

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

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

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

    
43
require_once("ipsec.inc");
44
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 $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
		/* IPSEC is off, shutdown enc interface.*/
147
		mwexec("/sbin/ifconfig enc0 down");
148

    
149
		return 0;
150
	}
151

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

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

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

    
166
	/* needed for config files */
167
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
168
		mkdir("{$g['varetc_path']}/ipsec");
169
	}
170
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
171
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
172
	}
173
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
174
	rmdir_recursive($capath);
175
	rmdir_recursive($keypath);
176
	rmdir_recursive($crlpath);
177
	rmdir_recursive($certpath);
178
	if (!is_dir($capath)) {
179
		mkdir($capath);
180
	}
181
	if (!is_dir($keypath)) {
182
		mkdir($keypath);
183
	}
184
	if (!is_dir($crlpath)) {
185
		mkdir($crlpath);
186
	}
187
	if (!is_dir($certpath)) {
188
		mkdir($certpath);
189
	}
190
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
191
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
192
	}
193
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
194
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
195
	}
196
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
197
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
198
	}
199
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
200
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
201
	}
202

    
203

    
204
	if (platform_booting()) {
205
		echo gettext("Configuring IPsec VPN... ");
206
	}
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
	$mobile_ipsec_auth = "";
217
	if (is_array($a_phase1) && count($a_phase1)) {
218

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

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

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

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

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

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

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

    
259
			if (isset ($ph1ent['mobile'])) {
260
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
261
				continue;
262
			}
263

    
264
			$rg = $ph1ent['remote-gateway'];
265

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

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

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

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

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

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

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

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

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

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

    
399
	unset($stronconf);
400

    
401
	$strongswanlog = "";
402
	$ipsecloglevels = vpn_ipsec_configure_loglevels(true);
403
	if (is_array($ipsecloglevels)) {
404
		foreach ($ipsecloglevels as $loglevel) {
405
			$strongswanlog .= "\t\t" . $loglevel . "\n";
406
		}
407
	}
408
	$strongswan = <<<EOD
409

    
410
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
411
starter {
412
load_warning = no
413
}
414

    
415
charon {
416
# number of worker threads in charon
417
threads = 16
418
ikesa_table_size = 32
419
ikesa_table_segments = 4
420
init_limit_half_open = 1000
421
install_routes = no
422
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
423
{$accept_unencrypted}
424
cisco_unity = {$unity_enabled}
425
{$ifacesuse}
426
{$makebeforebreak}
427

    
428
syslog {
429
	identifier = charon
430
	# log everything under daemon since it ends up in the same place regardless with our syslog.conf
431
	daemon {
432
		ike_name = yes
433
{$strongswanlog}
434
	}
435
	# disable logging under auth so logs aren't duplicated 
436
	auth {
437
		default = -1
438
	}
439
}
440

    
441
EOD;
442

    
443
	$strongswan .= "\tplugins {\n";
444

    
445
	/* Find RADIUS servers designated for Mobile IPsec user auth */
446
	$radius_server_txt = "";
447
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
448
	foreach ($user_sources as $user_source) {
449
		$auth_server = auth_get_authserver($user_source);
450
		$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
451
		if ($auth_server && $auth_server['type'] === 'radius') {
452
			$radius_server_txt .= <<<EOD
453
				{$nice_user_source} {
454
					address = {$auth_server['host']}
455
					secret = {$auth_server['radius_secret']}
456
					auth_port = {$auth_server['radius_auth_port']}
457
					acct_port = {$auth_server['radius_acct_port']}
458
				}
459

    
460
EOD;
461
		}
462
	}
463

    
464
	/* write an eap-radius config section if appropriate */
465
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
466
		$strongswan .= <<<EOD
467
		eap-radius {
468
			class_group = yes
469
			eap_start = no
470
			servers {
471
{$radius_server_txt}
472
			}
473
		}
474

    
475
EOD;
476
	}
477

    
478
	if (is_array($a_client) && isset($a_client['enable'])) {
479
		$strongswan .= "\t\tattr {\n";
480

    
481
		$cfgservers = array();
482
		if (!empty($a_client['dns_server1'])) {
483
			$cfgservers[] = $a_client['dns_server1'];
484
		}
485
		if (!empty($a_client['dns_server2'])) {
486
			$cfgservers[] = $a_client['dns_server2'];
487
		}
488
		if (!empty($a_client['dns_server3'])) {
489
			$cfgservers[] = $a_client['dns_server3'];
490
		}
491
		if (!empty($a_client['dns_server4'])) {
492
			$cfgservers[] = $a_client['dns_server4'];
493
		}
494

    
495
		if (!empty($cfgservers)) {
496
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
497
		}
498
		unset($cfgservers);
499
		$cfgservers = array();
500
		if (!empty($a_client['wins_server1'])) {
501
			$cfgservers[] = $a_client['wins_server1'];
502
		}
503
		if (!empty($a_client['wins_server2'])) {
504
			$cfgservers[] = $a_client['wins_server2'];
505
		}
506
		if (!empty($cfgservers)) {
507
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
508
		}
509
		unset($cfgservers);
510

    
511
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
512
			$net_list = '';
513
			foreach ($a_phase2 as $ph2ent) {
514
				if (isset($ph2ent['disabled'])) {
515
					continue;
516
				}
517

    
518
				if (!isset($ph2ent['mobile'])) {
519
					continue;
520
				}
521

    
522
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
523

    
524
				if (!empty($net_list)) {
525
					$net_list .= ",";
526
				}
527
				$net_list .= $localid;
528
			}
529

    
530
			if (!empty($net_list)) {
531
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
532
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
533
				unset($net_list);
534
			}
535
		}
536

    
537
		if (!empty($a_client['dns_domain'])) {
538
			$strongswan .= "\t\t\t# Search domain and default domain\n";
539
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
540
			if (empty($a_client['dns_split'])) {
541
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
542
			}
543
			$strongswan .= "\n";
544
		}
545

    
546
		if (!empty($a_client['dns_split'])) {
547
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
548
		}
549

    
550
		if (!empty($a_client['login_banner'])) {
551
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
552
		}
553

    
554
		if (isset($a_client['save_passwd'])) {
555
			$strongswan .= "\t\t\t28673 = 1\n";
556
		}
557

    
558
		if ($a_client['pfs_group']) {
559
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
560
		}
561
		$strongswan .= "\t\t}\n";
562

    
563
		if ($a_client['user_source'] != "none") {
564
			$strongswan .= "\t\txauth-generic {\n";
565
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
566
			$strongswan .= "\t\t\tauthcfg = ";
567
			$firstsed = 0;
568
			$authcfgs = explode(",", $a_client['user_source']);
569
			foreach ($authcfgs as $authcfg) {
570
				if ($firstsed > 0) {
571
					$strongswan .= ",";
572
				}
573
				if ($authcfg == "system") {
574
					$authcfg = "Local Database";
575
				}
576
				$strongswan .= $authcfg;
577
				$firstsed = 1;
578
			}
579
			$strongswan .= "\n";
580
			$strongswan .= "\t\t}\n";
581
		}
582
	}
583

    
584
	$strongswan .= "\t}\n}\n";
585
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
586
	unset($strongswan);
587

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

    
603
	$pskconf = "";
604

    
605
	$vpncas = array();
606
	if (is_array($a_phase1) && count($a_phase1)) {
607
		foreach ($a_phase1 as $ph1ent) {
608

    
609
			if (isset($ph1ent['disabled'])) {
610
				continue;
611
			}
612

    
613
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
614
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
615
				$certline = '';
616

    
617
				$ikeid = $ph1ent['ikeid'];
618
				$cert = lookup_cert($ph1ent['certref']);
619

    
620
				if (!$cert) {
621
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
622
					continue;
623
				}
624

    
625
				/* add signing CA cert chain of server cert
626
				 * to the list of CAs to write
627
				 */
628
				$cachain = ca_chain_array($cert);
629
				if ($cachain && is_array($cachain)) {
630
					foreach ($cachain as $cacrt) {
631
						$vpncas[$cacrt['refid']] = $cacrt;
632
					}
633
				}
634

    
635
				@chmod($certpath, 0600);
636

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

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

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

    
658
				$myid = trim($myid_data);
659

    
660
				if (empty($peerid_data)) {
661
					continue;
662
				}
663

    
664
				if ($myid_type == 'fqdn' && !empty($myid)) {
665
					$myid = "@{$myid}";
666
				}
667

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

    
670
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
671

    
672
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
673
					$peerid = "@{$peerid}";
674
				}
675

    
676
				if (!empty($ph1ent['pre-shared-key'])) {
677
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
678
					if (isset($ph1ent['mobile'])) {
679
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
680
					}
681
				}
682
			}
683

    
684
			/* if the client authenticates with a cert add the
685
			 * client cert CA chain to the list of CAs to write
686
			 */
687
			if (in_array($ph1ent['authentication_method'],
688
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
689

    
690
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
691
					$thisca = lookup_ca($ph1ent['caref']);
692
					$vpncas[$ph1ent['caref']] = $thisca;
693

    
694
					/* follow chain up to root */
695
					$cachain = ca_chain_array($thisca);
696
					if ($cachain and is_array($cachain)) {
697
						foreach ($cachain as $cacrt) {
698
							$vpncas[$cacrt['refid']] = $cacrt;
699
						}
700
					}
701
				}
702
			}
703
		}
704
	}
705

    
706
	/* write the required CAs */
707
	foreach ($vpncas as $carefid => $cadata) {
708
		$cacrt = base64_decode($cadata['crt']);
709
		$cacrtattrs = openssl_x509_parse($cacrt);
710
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
711
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
712
			continue;
713
		}
714
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
715
		if (!@file_put_contents($cafilename, $cacrt)) {
716
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
717
				continue;
718
		}
719
	}
720

    
721
	/* Add user PSKs */
722
	if (is_array($config['system']) && is_array($config['system']['user'])) {
723
		foreach ($config['system']['user'] as $user) {
724
			if (!empty($user['ipsecpsk'])) {
725
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
726
			}
727
		}
728
		unset($user);
729
	}
730

    
731
	/* add PSKs for mobile clients */
732
	if (is_array($ipseccfg['mobilekey'])) {
733
		foreach ($ipseccfg['mobilekey'] as $key) {
734
			if ($key['ident'] == "allusers") {
735
				$key['ident'] = '%any';
736
			}
737
			if ($key['ident'] == "any") {
738
				$key['ident'] = '%any';
739
			}
740
			if (empty($key['type'])) {
741
				$key['type'] = 'PSK';
742
			}
743
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
744
		}
745
		unset($key);
746
	}
747

    
748
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
749
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
750
	unset($pskconf);
751

    
752
	$uniqueids = 'yes';
753
	if (!empty($config['ipsec']['uniqueids'])) {
754
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
755
			$uniqueids = $config['ipsec']['uniqueids'];
756
		}
757
	}
758
	$natfilterrules = false;
759
	/* begin ipsec.conf */
760
	$ipsecconf = "";
761
	$enablecompression = false;
762
	if (is_array($a_phase1) && count($a_phase1)) {
763

    
764
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
765
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
766

    
767
		if (isset($config['ipsec']['strictcrlpolicy'])) {
768
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
769
		}
770

    
771
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
772
			if ($config['interfaces']['lan']) {
773
				$lanip = get_interface_ip("lan");
774
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
775
					$lansn = get_interface_subnet("lan");
776
					$lansa = gen_subnet($lanip, $lansn);
777
					$ipsecconf .= <<<EOD
778

    
779
conn bypasslan
780
	leftsubnet = {$lansa}/{$lansn}
781
	rightsubnet = {$lansa}/{$lansn}
782
	authby = never
783
	type = passthrough
784
	auto = route
785

    
786
EOD;
787
				}
788
			}
789
		}
790

    
791
		foreach ($a_phase1 as $ph1ent) {
792
			if (isset($ph1ent['disabled'])) {
793
				continue;
794
			}
795

    
796
			if ($ph1ent['mode'] == "aggressive") {
797
				$aggressive = "yes";
798
			} else {
799
				$aggressive = "no";
800
			}
801

    
802
			$ep = ipsec_get_phase1_src($ph1ent);
803
			if (!$ep) {
804
				continue;
805
			}
806

    
807
			$ikeid = $ph1ent['ikeid'];
808
			$keyexchange = "ikev1";
809
			$passive = "route";
810
			if (!empty($ph1ent['iketype'])) {
811
				if ($ph1ent['iketype'] == "ikev2") {
812
					$keyexchange = "ikev2";
813
					//$passive = "start";
814
				}
815
			}
816

    
817
			if (isset($ph1ent['mobile'])) {
818
				$right_spec = "%any";
819
				$passive = 'add';
820
			} else {
821
				if (isset($ph1ent['responderonly'])) {
822
					$passive = 'add';
823
				}
824

    
825
				$right_spec = $ph1ent['remote-gateway'];
826
				if (is_ipaddr($right_spec)) {
827
					$sourcehost = $right_spec;
828
				} else {
829
					$sourcehost = $rgmap['remote-gateway'];
830
				}
831

    
832
				if ($ph1ent['protocol'] == 'inet') {
833
					if (strpos($ph1ent['interface'], '_vip')) {
834
						$vpninterface = explode('_vip', $ph1ent['interface']);
835
						$ifacesuse = get_real_interface($vpninterface[0]);
836
						$vpninterface = $vpninterface[0];
837
					} else {
838
						$ifacesuse = get_failover_interface($ph1ent['interface']);
839
						if (strpos($ifacesuse, '_vip')) {
840
							$vpninterface = explode('_vip', $ifacesuse);
841
							$ifacesuse = get_real_interface($vpninterface[0]);
842
							$vpninterface = $vpninterface[0];
843
						} else {
844
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
845
						}
846
					}
847

    
848
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
849
						$gatewayip = get_interface_gateway($vpninterface);
850
						$interfaceip = get_interface_ip($vpninterface);
851
						$subnet_bits = get_interface_subnet($vpninterface);
852
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
853
						/* if the remote gateway is in the local subnet, then don't add a route */
854
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
855
							if (is_ipaddrv4($gatewayip)) {
856
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
857
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
858
							}
859
						}
860
					}
861
				} else if ($ph1ent['protocol'] == 'inet6') {
862
					if (strpos($ph1ent['interface'], '_vip')) {
863
						$vpninterface = explode('_vip', $ph1ent['interface']);
864
						$ifacesuse = get_real_interface($vpninterface[0]);
865
						$vpninterface = $vpninterface[0];
866
					} else {
867
						$ifacesuse = get_failover_interface($ph1ent['interface']);
868
						if (strpos($ifacesuse, '_vip')) {
869
							$vpninterface = explode('_vip', $ifacesuse);
870
							$ifacesuse = get_real_interface($vpninterface[0]);
871
							$vpninterface = $vpninterface[0];
872
						} else {
873
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
874
						}
875
					}
876

    
877
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
878
						$gatewayip = get_interface_gateway_v6($vpninterface);
879
						$interfaceip = get_interface_ipv6($vpninterface);
880
						$subnet_bits = get_interface_subnetv6($vpninterface);
881
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
882
						/* if the remote gateway is in the local subnet, then don't add a route */
883
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
884
							if (is_ipaddrv6($gatewayip)) {
885
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
886
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
887
							}
888
						}
889
					}
890
				}
891
			}
892

    
893
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
894
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
895
				$myid_data = "{$myid_type}:{$myid_data}";
896
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
897
				if ($myid_data[0] == '#') {
898
				/* asn1dn needs double quotes */
899
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
900
				} else {
901
					$myid_data = "\"{$myid_data}\"";
902
				}
903
			}
904
			$leftid = '';
905
			if (!empty($myid_data)) {
906
				$leftid = "leftid = {$myid_data}";
907
			}
908

    
909
			$peerid_spec = '';
910
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
911
				// Only specify peer ID if we are not dealing with mobile PSK
912
			} else {
913
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
914
				if ($peerid_type == 'any') {
915
					$peerid_spec = '';
916
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
917
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
918
				} elseif ($peerid_type == "asn1dn") {
919
					/* asn1dn needs double quotes */
920
					if ($peerid_data[0] == '#') {
921
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
922
					} elseif (!empty($peerid_data)) {
923
						$peerid_spec = "\"{$peerid_data}\"";
924
					}
925
				} else {
926
					$peerid_spec = $peerid_data;
927
				}
928
			}
929

    
930
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
931
				$ealgosp1 = '';
932
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
933
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
934
				if ($ealg_kl) {
935
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
936
				} else {
937
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
938
				}
939

    
940
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
941
				if (!empty($modp)) {
942
					$ealgosp1 .= "-{$modp}";
943
				}
944

    
945
				$ealgosp1 .= "!";
946
			}
947

    
948
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
949
				if ($passive == "route") {
950
					$dpdline = "dpdaction = restart";
951
				} else {
952
					$dpdline = "dpdaction = clear";
953
				}
954
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
955
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
956
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
957
			} else {
958
				$dpdline = "dpdaction = none";
959
			}
960

    
961
			$ikelifeline = '';
962
			if ($ph1ent['lifetime']) {
963
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
964
			}
965

    
966
			$rightsourceip = NULL;
967
			if (isset($ph1ent['mobile'])) {
968
				$rightsourceips = array();
969
				if (!empty($a_client['pool_address'])) {
970
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
971
				}
972
				if (!empty($a_client['pool_address_v6'])) {
973
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
974
				}
975
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
976
					$rightsourceips[] = "%radius";
977
				}
978
				if (count($rightsourceips)) {
979
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
980
				}
981
			}
982

    
983
			if (!empty($ph1ent['caref'])) {
984
				$ca = lookup_ca($ph1ent['caref']);
985
				if ($ca) {
986
					$casubarr = cert_get_subject_array($ca['crt']);
987
					$casub = "";
988
					foreach ($casubarr as $casubfield) {
989
						if (empty($casub)) {
990
							$casub = "/";
991
						}
992
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
993
					}
994

    
995
				}
996
			}
997

    
998
			$authentication = "";
999
			switch ($ph1ent['authentication_method']) {
1000
				case 'eap-mschapv2':
1001
					if (isset($ph1ent['mobile'])) {
1002
						$authentication = "eap_identity=%any\n\t";
1003
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1004
						if (!empty($ph1ent['certref'])) {
1005
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1006
							$authentication .= "\n\tleftsendcert=always";
1007
						}
1008
					}
1009
					break;
1010
				case 'eap-tls':
1011
					if (isset($ph1ent['mobile'])) {
1012
						$authentication = "eap_identity=%identity\n\t";
1013
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1014
						if (!empty($ph1ent['certref'])) {
1015
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1016
							$authentication .= "\n\tleftsendcert=always";
1017
						}
1018
					} else {
1019
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1020
						if (!empty($ph1ent['certref'])) {
1021
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1022
							$authentication .= "\n\tleftsendcert=always";
1023
						}
1024
					}
1025
					if (isset($casub)) {
1026
						$authentication .= "\n\trightca=\"$casub\"";
1027
					}
1028
					break;
1029
				case 'eap-radius':
1030
					if (isset($ph1ent['mobile'])) {
1031
						$authentication = "eap_identity=%identity\n\t";
1032
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1033
						if (!empty($ph1ent['certref'])) {
1034
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1035
							$authentication .= "\n\tleftsendcert=always";
1036
						}
1037
					} else {
1038
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1039
						if (!empty($ph1ent['certref'])) {
1040
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1041
							$authentication .= "\n\tleftsendcert=always";
1042
						}
1043
					}
1044
					break;
1045
				case 'xauth_rsa_server':
1046
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1047
					$authentication .= "\n\trightauth2 = xauth-generic";
1048
					if (!empty($ph1ent['certref'])) {
1049
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1050
					}
1051
					if (isset($casub)) {
1052
						$authentication .= "\n\trightca=\"$casub\"";
1053
					}
1054
					break;
1055
				case 'xauth_psk_server':
1056
					$authentication = "leftauth = psk\n\trightauth = psk";
1057
					$authentication .= "\n\trightauth2 = xauth-generic";
1058
					break;
1059
				case 'pre_shared_key':
1060
					$authentication = "leftauth = psk\n\trightauth = psk";
1061
					break;
1062
				case 'rsasig':
1063
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1064
					if (!empty($ph1ent['certref'])) {
1065
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1066
					}
1067
					if (isset($casub)) {
1068
						$authentication .= "\n\trightca=\"$casub\"";
1069
					}
1070
					break;
1071
				case 'hybrid_rsa_server':
1072
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1073
					if (!empty($ph1ent['certref'])) {
1074
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1075
					}
1076
					break;
1077
			}
1078

    
1079
			$left_spec = $ep;
1080

    
1081
			if (isset($ph1ent['reauth_enable'])) {
1082
				$reauth = "reauth = no";
1083
			} else {
1084
				$reauth = "reauth = yes";
1085
			}
1086
			if (isset($ph1ent['rekey_enable'])) {
1087
				$rekey = "rekey = no";
1088
			} else {
1089
				$rekey = "rekey = yes";
1090
			}
1091

    
1092
			if ($ph1ent['nat_traversal'] == 'off') {
1093
				$forceencaps = 'forceencaps = no';
1094
			} else if ($ph1ent['nat_traversal'] == 'force') {
1095
				$forceencaps = 'forceencaps = yes';
1096
			} else {
1097
				$forceencaps = 'forceencaps = no';
1098
			}
1099

    
1100
			if ($ph1ent['mobike'] == 'on') {
1101
				$mobike = 'mobike = yes';
1102
			} else {
1103
				$mobike = 'mobike = no';
1104
			}
1105

    
1106
			$ipseclifetime = 0;
1107
			$rightsubnet_spec = array();
1108
			$leftsubnet_spec = array();
1109
			$reqids = array();
1110
			$ealgoAHsp2arr = array();
1111
			$ealgoESPsp2arr = array();
1112
		if (is_array($a_phase2) && count($a_phase2)) {
1113
			foreach ($a_phase2 as $ph2ent) {
1114
				if ($ikeid != $ph2ent['ikeid']) {
1115
					continue;
1116
				}
1117

    
1118
				if (isset($ph2ent['disabled'])) {
1119
					continue;
1120
				}
1121

    
1122
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1123
					continue;
1124
				}
1125

    
1126
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1127
					$tunneltype = "type = tunnel";
1128

    
1129
					$localid_type = $ph2ent['localid']['type'];
1130
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1131

    
1132
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1133
					if (($localid_type == "none" || $localid_type == "mobile") &&
1134
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1135
						$left_spec = '%any';
1136
					} else {
1137
						if ($localid_type != "address") {
1138
							$localid_type = "subnet";
1139
						}
1140
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1141
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1142
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1143
							continue;
1144
						}
1145
						if (!empty($ph2ent['natlocalid'])) {
1146
							$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1147
							if ($ph2ent['natlocalid']['type'] != "address") {
1148
								if (is_subnet($natleftsubnet_data)) {
1149
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1150
								}
1151
							} else {
1152
								if (is_ipaddr($natleftsubnet_data)) {
1153
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1154
								}
1155
							}
1156
							$natfilterrules = true;
1157
						}
1158
					}
1159

    
1160
					$leftsubnet_spec[] = $leftsubnet_data;
1161

    
1162
					if (!isset($ph2ent['mobile'])) {
1163
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1164
						$rightsubnet_spec[] = $tmpsubnet;
1165
					} else if (!empty($a_client['pool_address'])) {
1166
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1167
					}
1168
				} else {
1169
					$tunneltype = "type = transport";
1170

    
1171
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1172
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
1173
						$left_spec = "%any";
1174
					} else {
1175
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1176
						$leftsubnet_spec[] = $tmpsubnet;
1177
					}
1178

    
1179
					if (!isset($ph2ent['mobile'])) {
1180
						$rightsubnet_spec[] = $right_spec;
1181
					}
1182
				}
1183

    
1184
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1185
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1186
				}
1187

    
1188
				if ($ph2ent['protocol'] == 'esp') {
1189
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1190
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1191
							$ealg_id = $ealg['name'];
1192
							$ealg_kl = $ealg['keylen'];
1193

    
1194
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
1195
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1196
									require("ipsec.inc");
1197
								}
1198
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1199
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1200
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1201
								/* XXX: in some cases where include ordering is suspect these variables
1202
								 * are somehow 0 and we enter this loop forever and timeout after 900
1203
								 * seconds wrecking bootup */
1204
								if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1205
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1206
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1207
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1208
												$halgo = str_replace('hmac_', '', $halgo);
1209
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1210
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1211
												if (!empty($modp)) {
1212
													$tmpealgo .= "-{$modp}";
1213
												}
1214
												$ealgoESPsp2arr[] = $tmpealgo;
1215
											}
1216
										} else {
1217
											$tmpealgo = "{$ealg_id}{$keylen}";
1218
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1219
											if (!empty($modp)) {
1220
												$tmpealgo .= "-{$modp}";
1221
											}
1222
											$ealgoESPsp2arr[] = $tmpealgo;
1223
										}
1224
									}
1225
								}
1226
							} else {
1227
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1228
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1229
										$halgo = str_replace('hmac_', '', $halgo);
1230
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1231
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1232
										if (!empty($modp)) {
1233
											$tmpealgo .= "-{$modp}";
1234
										}
1235
										$ealgoESPsp2arr[] = $tmpealgo;
1236
									}
1237
								} else {
1238
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1239
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1240
									if (!empty($modp)) {
1241
										$tmpealgo .= "-{$modp}";
1242
									}
1243
									$ealgoESPsp2arr[] = $tmpealgo;
1244
								}
1245
							}
1246
						}
1247
					}
1248
				} else if ($ph2ent['protocol'] == 'ah') {
1249
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1250
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1251
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1252
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1253
							if (!empty($modp)) {
1254
								$tmpAHalgo = "-{$modp}";
1255
							}
1256
							$ealgoAHsp2arr[] = $tmpAHalgo;
1257
						}
1258
					}
1259
				}
1260

    
1261
				$reqids[] = $ph2ent['reqid'];
1262

    
1263
				if (!empty($ph2ent['lifetime'])) {
1264
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1265
						$ipseclifetime = intval($ph2ent['lifetime']);
1266
					}
1267
				}
1268

    
1269
			}
1270
		}
1271

    
1272
			$ipsecconnect =<<<EOD
1273
	fragmentation = yes
1274
	keyexchange = {$keyexchange}
1275
	{$reauth}
1276
	{$forceencaps}
1277
	{$mobike}
1278
	{$rekey}
1279
	installpolicy = yes
1280
	{$tunneltype}
1281
	{$dpdline}
1282
	auto = {$passive}
1283
	left = {$left_spec}
1284
	right = {$right_spec}
1285
	{$leftid}
1286

    
1287
EOD;
1288

    
1289
			if (isset($config['ipsec']['compression'])) {
1290
				$ipsecconnect .= "\tcompress = yes\n";
1291
				$enablecompression = true;
1292
			}
1293
			if (!empty($ikelifeline)) {
1294
				$ipsecconnect .= "\t{$ikelifeline}\n";
1295
			}
1296
			if ($ipseclifetime > 0) {
1297
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1298
			}
1299
			if (!empty($rightsourceip)) {
1300
				$ipsecconnect .= "{$rightsourceip}";
1301
			}
1302
			if (!empty($ealgosp1)) {
1303
				$ipsecconnect .= "\t{$ealgosp1}\n";
1304
			}
1305
			if (!empty($ealgoAHsp2arr)) {
1306
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1307
			}
1308
			if (!empty($ealgoESPsp2arr)) {
1309
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1310
			}
1311
			if (!empty($authentication)) {
1312
				$ipsecconnect .= "\t{$authentication}\n";
1313
			}
1314
			if (!empty($peerid_spec)) {
1315
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1316
			}
1317
			if ($keyexchange == 'ikev1') {
1318
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1319
			}
1320

    
1321
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1322
				if (!empty($rightsubnet_spec)) {
1323
					$ipsecfin = '';
1324
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1325
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1326
						//if (!empty($reqids[$idx])) {
1327
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1328
						//}
1329
						$ipsecfin .= $ipsecconnect;
1330
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1331
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1332
					}
1333
				} else {
1334
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1335
				}
1336
			} else {
1337
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1338
				//if (!empty($reqids[$idx])) {
1339
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1340
				//}
1341
				$ipsecfin .= $ipsecconnect;
1342
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1343
					$tempsubnets = array();
1344
					foreach ($rightsubnet_spec as $rightsubnet) {
1345
						$tempsubnets[$rightsubnet] = $rightsubnet;
1346
					}
1347
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1348
					unset($tempsubnets, $rightsubnet);
1349
				}
1350
				if (!empty($leftsubnet_spec)) {
1351
					$tempsubnets = array();
1352
					foreach ($leftsubnet_spec as $leftsubnet) {
1353
						$tempsubnets[$leftsubnet] = $leftsubnet;
1354
					}
1355
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1356
					unset($tempsubnets, $leftsubnet);
1357
				}
1358
			}
1359
			$ipsecconf .= $ipsecfin;
1360
			unset($ipsecfin);
1361
		}
1362
	}
1363

    
1364
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1365
	unset($ipsecconf);
1366
	/* end ipsec.conf */
1367

    
1368
	if ($enablecompression === true) {
1369
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1370
	} else {
1371
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1372
	}
1373

    
1374
	/* manage process */
1375
	if ($restart === true) {
1376
		mwexec("/usr/local/sbin/ipsec restart", false);
1377
	} else {
1378
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1379
			/* Update configuration changes */
1380
			/* Read secrets */
1381
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1382
			mwexec("/usr/local/sbin/ipsec reload", false);
1383
		} else {
1384
			mwexec("/usr/local/sbin/ipsec start", false);
1385
		}
1386
	}
1387

    
1388
	if ($natfilterrules == true) {
1389
		filter_configure();
1390
	}
1391
	/* start filterdns, if necessary */
1392
	if (count($filterdns_list) > 0) {
1393
		$interval = 60;
1394
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1395
			$interval = $ipseccfg['dns-interval'];
1396
		}
1397

    
1398
		$hostnames = "";
1399
		array_unique($filterdns_list);
1400
		foreach ($filterdns_list as $hostname) {
1401
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1402
		}
1403
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1404
		unset($hostnames);
1405

    
1406
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1407
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1408
		} else {
1409
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1410
		}
1411
	} else {
1412
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1413
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1414
	}
1415

    
1416
	if (platform_booting()) {
1417
		echo "done\n";
1418
	}
1419

    
1420
	return count($filterdns_list);
1421
}
1422

    
1423
/*
1424
 * Forcefully restart IPsec
1425
 * This is required for when dynamic interfaces reload
1426
 * For all other occasions the normal vpn_ipsec_configure()
1427
 * will gracefully reload the settings without restarting
1428
 */
1429
function vpn_ipsec_force_reload($interface = "") {
1430
	global $g, $config;
1431

    
1432
	$ipseccfg = $config['ipsec'];
1433

    
1434
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1435
		$found = false;
1436
		foreach ($ipseccfg['phase1'] as $ipsec) {
1437
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1438
				$found = true;
1439
				break;
1440
			}
1441
		}
1442
		if (!$found) {
1443
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1444
			return;
1445
		}
1446
	}
1447

    
1448
	/* if ipsec is enabled, start up again */
1449
	if (isset($ipseccfg['enable'])) {
1450
		log_error(gettext("Forcefully reloading IPsec"));
1451
		vpn_ipsec_configure();
1452
	}
1453
}
1454

    
1455
/* master setup for vpn (mpd) */
1456
function vpn_setup() {
1457
	/* start pppoe server */
1458
	vpn_pppoes_configure();
1459

    
1460
	/* setup l2tp */
1461
	vpn_l2tp_configure();
1462
}
1463

    
1464
function vpn_netgraph_support() {
1465
	$iflist = get_configured_interface_list();
1466
	foreach ($iflist as $iface) {
1467
		$realif = get_real_interface($iface);
1468
		/* Get support for netgraph(4) from the nic */
1469
		$ifinfo = pfSense_get_interface_addresses($realif);
1470
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1471
			pfSense_ngctl_attach(".", $realif);
1472
		}
1473
	}
1474
}
1475

    
1476
function vpn_pppoes_configure() {
1477
	global $config;
1478

    
1479
	if (is_array($config['pppoes']['pppoe'])) {
1480
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1481
			vpn_pppoe_configure($pppoe);
1482
		}
1483
	}
1484
}
1485

    
1486
function vpn_pppoe_configure(&$pppoecfg) {
1487
	global $config, $g;
1488

    
1489
	$syscfg = $config['system'];
1490

    
1491
	/* create directory if it does not exist */
1492
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1493
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1494
	}
1495

    
1496
	if (platform_booting()) {
1497
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1498
			return 0;
1499
		}
1500

    
1501
		echo gettext("Configuring PPPoE Server service... ");
1502
	} else {
1503
		/* kill mpd */
1504
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1505

    
1506
		/* wait for process to die */
1507
		sleep(2);
1508

    
1509
	}
1510

    
1511
	switch ($pppoecfg['mode']) {
1512

    
1513
		case 'server':
1514

    
1515
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1516

    
1517
			if ($pppoecfg['paporchap'] == "chap") {
1518
				$paporchap = "set link enable chap";
1519
			} else {
1520
				$paporchap = "set link enable pap";
1521
			}
1522

    
1523
			/* write mpd.conf */
1524
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1525
			if (!$fd) {
1526
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1527
				return 1;
1528
			}
1529
			$mpdconf = "\n\n";
1530
			$mpdconf .= "poes:\n";
1531

    
1532
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1533
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1534
			}
1535

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

    
1538
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1539

    
1540
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1541
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1542
				} else {
1543
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1544
				}
1545

    
1546
				$mpdconf .=<<<EOD
1547

    
1548
poes{$pppoecfg['pppoeid']}{$i}:
1549
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1550
	{$issue_ip_type}
1551
	load pppoe_standard
1552

    
1553
EOD;
1554
			}
1555

    
1556
			$mpdconf .=<<<EOD
1557

    
1558
pppoe_standard:
1559
	set bundle no multilink
1560
	set bundle enable compression
1561
	set auth max-logins 1
1562
	set iface up-script /usr/local/sbin/vpn-linkup
1563
	set iface down-script /usr/local/sbin/vpn-linkdown
1564
	set iface idle 0
1565
	set iface disable on-demand
1566
	set iface disable proxy-arp
1567
	set iface enable tcpmssfix
1568
	set iface mtu 1500
1569
	set link no pap chap
1570
	{$paporchap}
1571
	set link keep-alive 60 180
1572
	set ipcp yes vjcomp
1573
	set ipcp no vjcomp
1574
	set link max-redial -1
1575
	set link mtu 1492
1576
	set link mru 1492
1577
	set ccp yes mpp-e40
1578
	set ccp yes mpp-e128
1579
	set ccp yes mpp-stateless
1580
	set link latency 1
1581
	#set ipcp dns 10.10.1.3
1582
	#set bundle accept encryption
1583

    
1584
EOD;
1585

    
1586
			if (!empty($pppoecfg['dns1'])) {
1587
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1588
				if (!empty($pppoecfg['dns2'])) {
1589
					$mpdconf .= " " . $pppoecfg['dns2'];
1590
				}
1591
				$mpdconf .= "\n";
1592
			} elseif (isset ($config['dnsmasq']['enable'])) {
1593
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1594
				if ($syscfg['dnsserver'][0]) {
1595
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1596
				}
1597
				$mpdconf .= "\n";
1598
			} elseif (isset ($config['unbound']['enable'])) {
1599
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1600
				if ($syscfg['dnsserver'][0]) {
1601
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1602
				}
1603
				$mpdconf .= "\n";
1604
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1605
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1606
			}
1607

    
1608
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1609
				$radiusport = "";
1610
				$radiusacctport = "";
1611
				if (isset($pppoecfg['radius']['server']['port'])) {
1612
					$radiusport = $pppoecfg['radius']['server']['port'];
1613
				}
1614
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1615
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1616
				}
1617
				$mpdconf .=<<<EOD
1618
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1619
	set radius retries 3
1620
	set radius timeout 10
1621
	set auth enable radius-auth
1622

    
1623
EOD;
1624

    
1625
				if (isset ($pppoecfg['radius']['accounting'])) {
1626
					$mpdconf .=<<<EOD
1627
	set auth enable radius-acct
1628

    
1629
EOD;
1630
				}
1631
			}
1632

    
1633
			fwrite($fd, $mpdconf);
1634
			fclose($fd);
1635
			unset($mpdconf);
1636

    
1637
			/* write mpd.links */
1638
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1639
			if (!$fd) {
1640
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1641
				return 1;
1642
			}
1643

    
1644
			$mpdlinks = "";
1645

    
1646
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1647
				$mpdlinks .=<<<EOD
1648

    
1649
poes{$pppoecfg['pppoeid']}{$i}:
1650
	set phys type pppoe
1651
	set pppoe iface {$pppoe_interface}
1652
	set pppoe service "*"
1653
	set pppoe disable originate
1654
	set pppoe enable incoming
1655

    
1656
EOD;
1657
			}
1658

    
1659
			fwrite($fd, $mpdlinks);
1660
			fclose($fd);
1661
			unset($mpdlinks);
1662

    
1663
			if ($pppoecfg['username']) {
1664
				/* write mpd.secret */
1665
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1666
				if (!$fd) {
1667
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1668
					return 1;
1669
				}
1670

    
1671
				$mpdsecret = "\n\n";
1672

    
1673
				if (!empty($pppoecfg['username'])) {
1674
					$item = explode(" ", $pppoecfg['username']);
1675
					foreach ($item as $userdata) {
1676
						$data = explode(":", $userdata);
1677
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1678
					}
1679
				}
1680

    
1681
				fwrite($fd, $mpdsecret);
1682
				fclose($fd);
1683
				unset($mpdsecret);
1684
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1685
			}
1686

    
1687
			/* Check if previous instance is still up */
1688
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1689
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1690
			}
1691

    
1692
			/* Get support for netgraph(4) from the nic */
1693
			pfSense_ngctl_attach(".", $pppoe_interface);
1694
			/* fire up mpd */
1695
			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");
1696

    
1697
			break;
1698
	}
1699

    
1700
	if (platform_booting()) {
1701
		echo gettext("done") . "\n";
1702
	}
1703

    
1704
	return 0;
1705
}
1706

    
1707
function vpn_l2tp_configure() {
1708
	global $config, $g;
1709

    
1710
	$syscfg = $config['system'];
1711
	$l2tpcfg = $config['l2tp'];
1712

    
1713
	/* create directory if it does not exist */
1714
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1715
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1716
	}
1717

    
1718
	if (platform_booting()) {
1719
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1720
			return 0;
1721
		}
1722

    
1723
		echo gettext("Configuring l2tp VPN service... ");
1724
	} else {
1725
		/* kill mpd */
1726
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1727

    
1728
		/* wait for process to die */
1729
		sleep(8);
1730

    
1731
	}
1732

    
1733
	/* make sure l2tp-vpn directory exists */
1734
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1735
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1736
	}
1737

    
1738
	switch ($l2tpcfg['mode']) {
1739

    
1740
		case 'server':
1741
			$l2tp_listen="";
1742
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1743
			if (is_ipaddrv4($ipaddr)) {
1744
				$l2tp_listen="set l2tp self $ipaddr";
1745
			}
1746

    
1747
			switch ($l2tpcfg['paporchap']) {
1748
				case 'chap':
1749
					$paporchap = "set link enable chap";
1750
					break;
1751
				case 'chap-msv2':
1752
					$paporchap = "set link enable chap-msv2";
1753
					break;
1754
				default:
1755
					$paporchap = "set link enable pap";
1756
					break;
1757
			}
1758

    
1759
			/* write mpd.conf */
1760
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1761
			if (!$fd) {
1762
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1763
				return 1;
1764
			}
1765
			$mpdconf = "\n\n";
1766
			$mpdconf .=<<<EOD
1767
l2tps:
1768

    
1769
EOD;
1770

    
1771
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1772
				$mpdconf .= "	load l2tp{$i}\n";
1773
			}
1774

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

    
1777
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1778

    
1779
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1780
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1781
				} else {
1782
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1783
				}
1784

    
1785
				$mpdconf .=<<<EOD
1786

    
1787
l2tp{$i}:
1788
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1789
	{$issue_ip_type}
1790
	load l2tp_standard
1791

    
1792
EOD;
1793
			}
1794

    
1795
			$mpdconf .=<<<EOD
1796

    
1797
l2tp_standard:
1798
	set bundle disable multilink
1799
	set bundle enable compression
1800
	set bundle yes crypt-reqd
1801
	set ipcp yes vjcomp
1802
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1803
	set ccp yes mppc
1804
	set iface disable on-demand
1805
	set iface enable proxy-arp
1806
	set iface up-script /usr/local/sbin/vpn-linkup
1807
	set iface down-script /usr/local/sbin/vpn-linkdown
1808
	set link yes acfcomp protocomp
1809
	set link no pap chap
1810
	{$paporchap}
1811
	{$l2tp_listen}
1812
	set link keep-alive 10 180
1813

    
1814
EOD;
1815

    
1816
			if (is_ipaddr($l2tpcfg['wins'])) {
1817
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1818
			}
1819
			if (is_ipaddr($l2tpcfg['dns1'])) {
1820
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1821
				if (is_ipaddr($l2tpcfg['dns2'])) {
1822
					$mpdconf .= " " . $l2tpcfg['dns2'];
1823
				}
1824
				$mpdconf .= "\n";
1825
			} elseif (isset ($config['dnsmasq']['enable'])) {
1826
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1827
				if ($syscfg['dnsserver'][0]) {
1828
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1829
				}
1830
				$mpdconf .= "\n";
1831
			} elseif (isset ($config['unbound']['enable'])) {
1832
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1833
				if ($syscfg['dnsserver'][0]) {
1834
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1835
				}
1836
				$mpdconf .= "\n";
1837
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1838
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1839
			}
1840

    
1841
			if (isset ($l2tpcfg['radius']['enable'])) {
1842
				$mpdconf .=<<<EOD
1843
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1844
	set radius retries 3
1845
	set radius timeout 10
1846
	set auth enable radius-auth
1847

    
1848
EOD;
1849

    
1850
				if (isset ($l2tpcfg['radius']['accounting'])) {
1851
					$mpdconf .=<<<EOD
1852
	set auth enable radius-acct
1853

    
1854
EOD;
1855
				}
1856
			}
1857

    
1858
			fwrite($fd, $mpdconf);
1859
			fclose($fd);
1860
			unset($mpdconf);
1861

    
1862
			/* write mpd.links */
1863
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1864
			if (!$fd) {
1865
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1866
				return 1;
1867
			}
1868

    
1869
			$mpdlinks = "";
1870

    
1871
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1872
				$mpdlinks .=<<<EOD
1873

    
1874
l2tp{$i}:
1875
	set link type l2tp
1876
	set l2tp enable incoming
1877
	set l2tp disable originate
1878

    
1879
EOD;
1880
				if (!empty($l2tpcfg['secret'])) {
1881
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1882
				}
1883
			}
1884

    
1885
			fwrite($fd, $mpdlinks);
1886
			fclose($fd);
1887
			unset($mpdlinks);
1888

    
1889
			/* write mpd.secret */
1890
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1891
			if (!$fd) {
1892
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1893
				return 1;
1894
			}
1895

    
1896
			$mpdsecret = "\n\n";
1897

    
1898
			if (is_array($l2tpcfg['user'])) {
1899
				foreach ($l2tpcfg['user'] as $user) {
1900
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1901
				}
1902
			}
1903

    
1904
			fwrite($fd, $mpdsecret);
1905
			fclose($fd);
1906
			unset($mpdsecret);
1907
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1908

    
1909
			vpn_netgraph_support();
1910

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

    
1914
			break;
1915

    
1916
		case 'redir':
1917
			break;
1918
	}
1919

    
1920
	if (platform_booting()) {
1921
		echo "done\n";
1922
	}
1923

    
1924
	return 0;
1925
}
1926

    
1927
?>
(59-59/67)