Project

General

Profile

Download (58.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
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
22
	   the documentation and/or other materials provided with the
23
	   distribution.
24

    
25
	3. All advertising materials mentioning features or use of this software
26
	   must display the following acknowledgment:
27
	   "This product includes software developed by the pfSense Project
28
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
29

    
30
	4. The names "pfSense" and "pfSense Project" must not be used to
31
	   endorse or promote products derived from this software without
32
	   prior written permission. For written permission, please contact
33
	   coreteam@pfsense.org.
34

    
35
	5. Products derived from this software may not be called "pfSense"
36
	   nor may "pfSense" appear in their names without prior written
37
	   permission of the Electric Sheep Fencing, LLC.
38

    
39
	6. Redistributions of any form whatsoever must retain the following
40
	   acknowledgment:
41

    
42
	"This product includes software developed by the pfSense Project
43
	for use in the pfSense software distribution (http://www.pfsense.org/).
44

    
45
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
	OF THE POSSIBILITY OF SUCH DAMAGE.
57
*/
58

    
59
require_once("ipsec.inc");
60
require_once("filter.inc");
61

    
62
function vpn_update_daemon_loglevel($category, $level) {
63
	global $ipsec_log_cats, $ipsec_log_sevs;
64

    
65
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
66

    
67
		/* if you're setting to -1, need to add "--" to args */
68
		$argterm = "";
69
		if ($level == "-1") {
70
			$argterm = "--";
71
		}
72

    
73
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
74
	}
75
}
76

    
77
function vpn_logging_cfgtxt() {
78
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
79

    
80
	$cfgtext = array();
81
	foreach (array_keys($ipsec_log_cats) as $cat) {
82
		if (is_numeric($config['ipsec']['logging'][$cat]) &&
83
		    in_array(intval($config['ipsec']['logging'][$cat]), array_keys($ipsec_log_sevs), true)) {
84
			$cfgtext[] = "${cat} = {$config['ipsec']['logging'][$cat]}";
85
		}
86
	}
87

    
88
	return $cfgtext;
89
}
90

    
91
/* include all configuration functions */
92
function vpn_ipsec_convert_to_modp($index) {
93

    
94
	$conversion = "";
95
	switch ($index) {
96
		case '1':
97
			$conversion = "modp768";
98
			break;
99
		case '2':
100
			$conversion = "modp1024";
101
			break;
102
		case '5':
103
			$conversion = "modp1536";
104
			break;
105
		case '14':
106
			$conversion = "modp2048";
107
			break;
108
		case '15':
109
			$conversion = "modp3072";
110
			break;
111
		case '16':
112
			$conversion = "modp4096";
113
			break;
114
		case '17':
115
			$conversion = "modp6144";
116
			break;
117
		case '18':
118
			$conversion = "modp8192";
119
			break;
120
		case '19':
121
			$conversion = "ecp256";
122
			break;
123
		case '20':
124
			$conversion = "ecp384";
125
			break;
126
		case '21':
127
			$conversion = "ecp521";
128
			break;
129
		case '22':
130
			$conversion = "modp1024s160";
131
			break;
132
		case '23':
133
			$conversion = "modp2048s224";
134
			break;
135
		case '24':
136
			$conversion = "modp2048s256";
137
			break;
138
		case '28':
139
			$conversion = "ecp256bp";
140
			break;
141
		case '29':
142
			$conversion = "ecp384bp";
143
			break;
144
		case '30':
145
			$conversion = "ecp512bp";
146
			break;
147
	}
148

    
149
	return $conversion;
150
}
151

    
152
function vpn_ipsec_configure($restart = false) {
153
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
154

    
155
	$ipsecstartlock = lock('ipsec', LOCK_EX);
156

    
157
	/* get the automatic ping_hosts.sh ready */
158
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
159
	touch("{$g['vardb_path']}/ipsecpinghosts");
160
	$ipsecpinghostsactive = false;
161

    
162
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
163
	filter_configure();
164

    
165
	$syscfg = $config['system'];
166
	$ipseccfg = $config['ipsec'];
167
	if (!ipsec_enabled()) {
168
		/* try to stop charon */
169
		mwexec("/usr/local/sbin/ipsec stop");
170
		/* Stop dynamic monitoring */
171
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
172

    
173
		/* wait for process to die */
174
		sleep(2);
175

    
176
		/* IPSEC is off, shutdown enc interface.*/
177
		mwexec("/sbin/ifconfig enc0 down");
178

    
179
		unlock($ipsecstartlock);
180
		return 0;
181
	}
182

    
183
	$a_phase1 = $config['ipsec']['phase1'];
184
	$a_phase2 = $config['ipsec']['phase2'];
185
	$a_client = $config['ipsec']['client'];
186

    
187
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
188
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
189
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
190
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
191

    
192
	mwexec("/sbin/ifconfig enc0 up");
193
	if (php_uname('m') != "amd64") {
194
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
195
	}
196

    
197
	/* needed for config files */
198
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
199
		mkdir("{$g['varetc_path']}/ipsec");
200
	}
201
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
202
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
203
	}
204
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
205
	rmdir_recursive($capath);
206
	rmdir_recursive($keypath);
207
	rmdir_recursive($crlpath);
208
	rmdir_recursive($certpath);
209
	if (!is_dir($capath)) {
210
		mkdir($capath);
211
	}
212
	if (!is_dir($keypath)) {
213
		mkdir($keypath);
214
	}
215
	if (!is_dir($crlpath)) {
216
		mkdir($crlpath);
217
	}
218
	if (!is_dir($certpath)) {
219
		mkdir($certpath);
220
	}
221
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
222
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
223
	}
224
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
225
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
226
	}
227
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
228
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
229
	}
230
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
231
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
232
	}
233

    
234
	if (!file_exists("/usr/local/etc/ipsec.d") ||
235
	    !is_link("/usr/local/etc/ipsec.d")) {
236
		conf_mount_rw();
237
		if (file_exists("/usr/local/etc/ipsec.d")) {
238
			rmdir_recursive("/usr/local/etc/ipsec.d");
239
		}
240
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
241
		    "/usr/local/etc/ipsec.d");
242
		conf_mount_ro();
243
	}
244
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
245
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
246
		conf_mount_rw();
247
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
248
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
249
		} else {
250
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
251
		}
252
		@symlink("/usr/local/etc/strongswan.d",
253
		    "{$g['varetc_path']}/ipsec/strongswan.d");
254
		conf_mount_ro();
255
	}
256
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
257
	    !is_link("/usr/local/etc/strongswan.conf")) {
258
		conf_mount_rw();
259
		@unlink("/usr/local/etc/strongswan.conf");
260
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
261
		    "/usr/local/etc/strongswan.conf");
262
		conf_mount_ro();
263
	}
264
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
265
	    !is_link("/usr/local/etc/ipsec.conf")) {
266
		conf_mount_rw();
267
		@unlink("/usr/local/etc/ipsec.conf");
268
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
269
		    "/usr/local/etc/ipsec.conf");
270
		conf_mount_ro();
271
	}
272

    
273
	if (platform_booting()) {
274
		echo gettext("Configuring IPsec VPN... ");
275
	}
276

    
277
	/* resolve all local, peer addresses and setup pings */
278
	$ipmap = array();
279
	$rgmap = array();
280
	$filterdns_list = array();
281
	$aggressive_mode_psk = false;
282
	unset($iflist);
283
	$ifacesuse = array();
284
	$mobile_ipsec_auth = "";
285
	if (is_array($a_phase1) && count($a_phase1)) {
286

    
287
		$ipsecpinghosts = "";
288
		/* step through each phase1 entry */
289
		foreach ($a_phase1 as $ph1ent) {
290
			if (isset($ph1ent['disabled'])) {
291
				continue;
292
			}
293

    
294
			if (substr($ph1ent['interface'], 0, 4) == "_vip") {
295
				$vpninterface = get_configured_vip_interface($ph1ent['interface']);
296
				$ifacesuse[] = get_real_interface($vpninterface);
297
			} else {
298
				$vpninterface = get_failover_interface($ph1ent['interface']);
299
				if (substr($vpninterface, 0, 4) == "_vip") {
300
					$vpninterface = get_configured_vip_interface($vpninterface);
301
					$ifacesuse[] = get_real_interface($vpninterface);
302
				} elseif (!empty($vpninterface)) {
303
					$ifacesuse[] = $vpninterface;
304
				}
305
			}
306

    
307
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
308
				$aggressive_mode_psk = true;
309
			}
310

    
311
			$ikeid = $ph1ent['ikeid'];
312

    
313
			$ep = ipsec_get_phase1_src($ph1ent);
314
			if (!is_ipaddr($ep)) {
315
				log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
316
				continue;
317
			}
318

    
319
			if (!in_array($ep, $ipmap)) {
320
				$ipmap[] = $ep;
321
			}
322

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

    
326
			if (isset ($ph1ent['mobile'])) {
327
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
328
				continue;
329
			}
330

    
331
			$rg = $ph1ent['remote-gateway'];
332

    
333
			if (!is_ipaddr($rg)) {
334
				$filterdns_list[] = "{$rg}";
335
				add_hostname_to_watch($rg);
336
				if (!platform_booting()) {
337
					$rg = resolve_retry($rg);
338
				}
339
				if (!is_ipaddr($rg)) {
340
					continue;
341
				}
342
			}
343
			if (array_search($rg, $rgmap)) {
344
				log_error(sprintf(gettext("The remote gateway %s already exists on another phase 1 entry"), $rg));
345
				continue;
346
			}
347
			$rgmap[$ph1ent['remote-gateway']] = $rg;
348

    
349
			if (is_array($a_phase2)) {
350
				/* step through each phase2 entry */
351
				foreach ($a_phase2 as $ph2ent) {
352
					if (isset($ph2ent['disabled'])) {
353
						continue;
354
					}
355

    
356
					if ($ikeid != $ph2ent['ikeid']) {
357
						continue;
358
					}
359

    
360
					/* add an ipsec pinghosts entry */
361
					if ($ph2ent['pinghost']) {
362
						if (!is_array($iflist)) {
363
							$iflist = get_configured_interface_list();
364
						}
365
						$srcip = null;
366
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
367
						if (is_ipaddrv6($ph2ent['pinghost'])) {
368
							foreach ($iflist as $ifent => $ifname) {
369
								$interface_ip = get_interface_ipv6($ifent);
370
								if (!is_ipaddrv6($interface_ip)) {
371
									continue;
372
								}
373
								if (ip_in_subnet($interface_ip, $local_subnet)) {
374
									$srcip = $interface_ip;
375
									break;
376
								}
377
							}
378
						} else {
379
							foreach ($iflist as $ifent => $ifname) {
380
								$interface_ip = get_interface_ip($ifent);
381
								if (!is_ipaddrv4($interface_ip)) {
382
									continue;
383
								}
384
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
385
									$srcip = $interface_ip;
386
									break;
387
								}
388
							}
389
						}
390
						/* if no valid src IP was found in configured interfaces, try the vips */
391
						if (is_null($srcip)) {
392
							$viplist = get_configured_vip_list();
393
							foreach ($viplist as $vip => $address) {
394
								if (ip_in_subnet($address, $local_subnet)) {
395
									$srcip = $address;
396
									break;
397
								}
398
							}
399
						}
400
						$dstip = $ph2ent['pinghost'];
401
						if (is_ipaddrv6($dstip)) {
402
							$family = "inet6";
403
						} else {
404
							$family = "inet";
405
						}
406
						if (is_ipaddr($srcip)) {
407
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
408
							$ipsecpinghostsactive = true;
409
						}
410
					}
411
				}
412
			}
413
		}
414
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
415
		unset($ipsecpinghosts);
416
	}
417
	unset($iflist);
418

    
419
	$accept_unencrypted = "";
420
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
421
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
422
	}
423

    
424
	$stronconf = '';
425
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
426
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
427
	}
428

    
429
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
430
	if ($aggressive_mode_psk) {
431
		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.");
432
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
433
			$restart = true;
434
		}
435
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
436
	}
437

    
438
	$unity_enabled = isset($config['ipsec']['unityplugin']) ? 'yes' : 'no';
439

    
440
	$makebeforebreak = '';
441
	if (isset($config['ipsec']['makebeforebreak'])) {
442
		$makebeforebreak = 'make_before_break = yes';
443
	}
444

    
445
	if (isset($config['ipsec']['enableinterfacesuse'])) {
446
		if (!empty($ifacesuse)) {
447
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
448
		} else {
449
			$ifacesuse = '';
450
		}
451
	} else {
452
		$ifacesuse = '';
453
	}
454

    
455
	unset($stronconf);
456

    
457
	$strongswanlog = "";
458
	$ipsecloglevels = vpn_logging_cfgtxt();
459
	if (is_array($ipsecloglevels)) {
460
		foreach ($ipsecloglevels as $loglevel) {
461
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
462
		}
463
	}
464
	$strongswan = <<<EOD
465

    
466
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
467
starter {
468
	load_warning = no
469
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
470
}
471

    
472
charon {
473
# number of worker threads in charon
474
	threads = 16
475
	ikesa_table_size = 32
476
	ikesa_table_segments = 4
477
	init_limit_half_open = 1000
478
	install_routes = no
479
	load_modular = yes
480
	ignore_acquire_ts = yes
481
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
482
	{$accept_unencrypted}
483
	cisco_unity = {$unity_enabled}
484
	{$ifacesuse}
485
	{$makebeforebreak}
486

    
487
	syslog {
488
		identifier = charon
489
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
490
		daemon {
491
			ike_name = yes
492
{$strongswanlog}
493
		}
494
		# disable logging under auth so logs aren't duplicated
495
		auth {
496
			default = -1
497
		}
498
	}
499

    
500
	plugins {
501
		# Load defaults
502
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
503

    
504
		stroke {
505
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
506
		}
507

    
508
		unity {
509
			load = {$unity_enabled}
510
		}
511

    
512
EOD;
513

    
514
	/* Find RADIUS servers designated for Mobile IPsec user auth */
515
	$radius_server_txt = "";
516
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
517
	foreach ($user_sources as $user_source) {
518
		$auth_server = auth_get_authserver($user_source);
519
		$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
520
		if ($auth_server && $auth_server['type'] === 'radius') {
521
			$radius_server_txt .= <<<EOD
522
				{$nice_user_source} {
523
					address = {$auth_server['host']}
524
					secret = "{$auth_server['radius_secret']}"
525
					auth_port = {$auth_server['radius_auth_port']}
526
					acct_port = {$auth_server['radius_acct_port']}
527
				}
528

    
529
EOD;
530
		}
531
	}
532

    
533
	/* write an eap-radius config section if appropriate */
534
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
535
		$strongswan .= <<<EOD
536
		eap-radius {
537
			class_group = yes
538
			eap_start = no
539
			servers {
540
{$radius_server_txt}
541
			}
542
		}
543

    
544
EOD;
545
	}
546

    
547
	if (is_array($a_client) && isset($a_client['enable'])) {
548
		$strongswan .= "\t\tattr {\n";
549

    
550
		$cfgservers = array();
551
		if (!empty($a_client['dns_server1'])) {
552
			$cfgservers[] = $a_client['dns_server1'];
553
		}
554
		if (!empty($a_client['dns_server2'])) {
555
			$cfgservers[] = $a_client['dns_server2'];
556
		}
557
		if (!empty($a_client['dns_server3'])) {
558
			$cfgservers[] = $a_client['dns_server3'];
559
		}
560
		if (!empty($a_client['dns_server4'])) {
561
			$cfgservers[] = $a_client['dns_server4'];
562
		}
563

    
564
		if (!empty($cfgservers)) {
565
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
566
		}
567
		unset($cfgservers);
568
		$cfgservers = array();
569
		if (!empty($a_client['wins_server1'])) {
570
			$cfgservers[] = $a_client['wins_server1'];
571
		}
572
		if (!empty($a_client['wins_server2'])) {
573
			$cfgservers[] = $a_client['wins_server2'];
574
		}
575
		if (!empty($cfgservers)) {
576
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
577
		}
578
		unset($cfgservers);
579

    
580
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
581
			$net_list = '';
582
			foreach ($a_phase2 as $ph2ent) {
583
				if (isset($ph2ent['disabled'])) {
584
					continue;
585
				}
586

    
587
				if (!isset($ph2ent['mobile'])) {
588
					continue;
589
				}
590

    
591
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
592

    
593
				if (!empty($net_list)) {
594
					$net_list .= ",";
595
				}
596
				$net_list .= $localid;
597
			}
598

    
599
			if (!empty($net_list)) {
600
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
601
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
602
				unset($net_list);
603
			}
604
		}
605

    
606
		if (!empty($a_client['dns_domain'])) {
607
			$strongswan .= "\t\t\t# Search domain and default domain\n";
608
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
609
			if (empty($a_client['dns_split'])) {
610
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
611
			}
612
			$strongswan .= "\n";
613
		}
614

    
615
		if (!empty($a_client['dns_split'])) {
616
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
617
		}
618

    
619
		if (!empty($a_client['login_banner'])) {
620
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
621
		}
622

    
623
		if (isset($a_client['save_passwd'])) {
624
			$strongswan .= "\t\t\t28673 = 1\n";
625
		}
626

    
627
		if ($a_client['pfs_group']) {
628
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
629
		}
630
		$strongswan .= "\t\t}\n";
631

    
632
		if ($a_client['user_source'] != "none") {
633
			$strongswan .= "\t\txauth-generic {\n";
634
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
635
			$strongswan .= "\t\t\tauthcfg = ";
636
			$firstsed = 0;
637
			$authcfgs = explode(",", $a_client['user_source']);
638
			foreach ($authcfgs as $authcfg) {
639
				if ($firstsed > 0) {
640
					$strongswan .= ",";
641
				}
642
				if ($authcfg == "system") {
643
					$authcfg = "Local Database";
644
				}
645
				$strongswan .= $authcfg;
646
				$firstsed = 1;
647
			}
648
			$strongswan .= "\n";
649
			$strongswan .= "\t\t}\n";
650
		}
651
	}
652

    
653
	$strongswan .= "\n\t}\n}\n";
654
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
655
	unset($strongswan);
656

    
657
	/* write out CRL files */
658
	if (is_array($config['crl']) && count($config['crl'])) {
659
		foreach ($config['crl'] as $crl) {
660
			if (!isset($crl['text'])) {
661
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
662
				continue;
663
			}
664
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
665
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
666
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
667
				continue;
668
			}
669
		}
670
	}
671

    
672
	$pskconf = "";
673

    
674
	$vpncas = array();
675
	if (is_array($a_phase1) && count($a_phase1)) {
676
		foreach ($a_phase1 as $ph1ent) {
677

    
678
			if (isset($ph1ent['disabled'])) {
679
				continue;
680
			}
681

    
682
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
683
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
684
				$certline = '';
685

    
686
				$ikeid = $ph1ent['ikeid'];
687
				$cert = lookup_cert($ph1ent['certref']);
688

    
689
				if (!$cert) {
690
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
691
					continue;
692
				}
693

    
694
				/* add signing CA cert chain of server cert
695
				 * to the list of CAs to write
696
				 */
697
				$cachain = ca_chain_array($cert);
698
				if ($cachain && is_array($cachain)) {
699
					foreach ($cachain as $cacrt) {
700
						$vpncas[$cacrt['refid']] = $cacrt;
701
					}
702
				}
703

    
704
				@chmod($certpath, 0600);
705

    
706
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
707
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
708
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
709
					continue;
710
				}
711
				@chmod($ph1keyfile, 0600);
712

    
713
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
714
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
715
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
716
					@unlink($ph1keyfile);
717
					continue;
718
				}
719
				@chmod($ph1certfile, 0600);
720

    
721
				/* XXX" Traffic selectors? */
722
				$pskconf .= " : RSA {$ph1keyfile}\n";
723
			} else {
724
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
725
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
726

    
727
				$myid = trim($myid_data);
728

    
729
				if (empty($peerid_data)) {
730
					continue;
731
				}
732

    
733
				if ($myid_type == 'fqdn' && !empty($myid)) {
734
					$myid = "@{$myid}";
735
				}
736

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

    
739
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
740

    
741
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
742
					$peerid = "@{$peerid}";
743
				}
744

    
745
				if (!empty($ph1ent['pre-shared-key'])) {
746
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
747
					if (isset($ph1ent['mobile'])) {
748
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
749
					}
750
				}
751
			}
752

    
753
			/* if the client authenticates with a cert add the
754
			 * client cert CA chain to the list of CAs to write
755
			 */
756
			if (in_array($ph1ent['authentication_method'],
757
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
758

    
759
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
760
					$thisca = lookup_ca($ph1ent['caref']);
761
					$vpncas[$ph1ent['caref']] = $thisca;
762

    
763
					/* follow chain up to root */
764
					$cachain = ca_chain_array($thisca);
765
					if ($cachain and is_array($cachain)) {
766
						foreach ($cachain as $cacrt) {
767
							$vpncas[$cacrt['refid']] = $cacrt;
768
						}
769
					}
770
				}
771
			}
772
		}
773
	}
774

    
775
	/* write the required CAs */
776
	foreach ($vpncas as $carefid => $cadata) {
777
		$cacrt = base64_decode($cadata['crt']);
778
		$cacrtattrs = openssl_x509_parse($cacrt);
779
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
780
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
781
			continue;
782
		}
783
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
784
		if (!@file_put_contents($cafilename, $cacrt)) {
785
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
786
				continue;
787
		}
788
	}
789

    
790
	/* Add user PSKs */
791
	if (is_array($config['system']) && is_array($config['system']['user'])) {
792
		foreach ($config['system']['user'] as $user) {
793
			if (!empty($user['ipsecpsk'])) {
794
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
795
			}
796
		}
797
		unset($user);
798
	}
799

    
800
	/* add PSKs for mobile clients */
801
	if (is_array($ipseccfg['mobilekey'])) {
802
		foreach ($ipseccfg['mobilekey'] as $key) {
803
			if ($key['ident'] == "allusers") {
804
				$key['ident'] = '%any';
805
			}
806
			if ($key['ident'] == "any") {
807
				$key['ident'] = '%any';
808
			}
809
			if (empty($key['type'])) {
810
				$key['type'] = 'PSK';
811
			}
812
			$pskconf .= " {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
813
		}
814
		unset($key);
815
	}
816

    
817
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
818
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
819
	unset($pskconf);
820

    
821
	$uniqueids = 'yes';
822
	if (!empty($config['ipsec']['uniqueids'])) {
823
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
824
			$uniqueids = $config['ipsec']['uniqueids'];
825
		}
826
	}
827
	$natfilterrules = false;
828
	/* begin ipsec.conf */
829
	$ipsecconf = "";
830
	$enablecompression = false;
831
	if (is_array($a_phase1) && count($a_phase1)) {
832

    
833
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
834
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
835

    
836
		if (isset($config['ipsec']['strictcrlpolicy'])) {
837
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
838
		}
839

    
840
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
841
			if ($config['interfaces']['lan']) {
842
				$lanip = get_interface_ip("lan");
843
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
844
					$lansn = get_interface_subnet("lan");
845
					$lansa = gen_subnet($lanip, $lansn);
846
					$ipsecconf .= <<<EOD
847

    
848
conn bypasslan
849
	leftsubnet = {$lansa}/{$lansn}
850
	rightsubnet = {$lansa}/{$lansn}
851
	authby = never
852
	type = passthrough
853
	auto = route
854

    
855
EOD;
856
				}
857
			}
858
		}
859

    
860
		foreach ($a_phase1 as $ph1ent) {
861
			if (isset($ph1ent['disabled'])) {
862
				continue;
863
			}
864

    
865
			if ($ph1ent['mode'] == "aggressive") {
866
				$aggressive = "yes";
867
			} else {
868
				$aggressive = "no";
869
			}
870

    
871
			$ep = ipsec_get_phase1_src($ph1ent);
872
			if (!$ep) {
873
				continue;
874
			}
875

    
876
			$ikeid = $ph1ent['ikeid'];
877
			$keyexchange = "ikev1";
878
			$passive = "route";
879
			if (!empty($ph1ent['iketype'])) {
880
				if ($ph1ent['iketype'] == "ikev2") {
881
					$keyexchange = "ikev2";
882
				} elseif ($ph1ent['iketype'] == "auto") {
883
					$keyexchange = "ike";
884
				}
885
			}
886

    
887
			if (isset($ph1ent['mobile'])) {
888
				$right_spec = "%any";
889
				$passive = 'add';
890
			} else {
891
				if (isset($ph1ent['responderonly'])) {
892
					$passive = 'add';
893
				}
894

    
895
				$right_spec = $ph1ent['remote-gateway'];
896
				if (is_ipaddr($right_spec)) {
897
					$sourcehost = $right_spec;
898
				} else {
899
					$sourcehost = $rgmap['remote-gateway'];
900
				}
901

    
902
				if ($ph1ent['protocol'] == 'inet') {
903
					if (substr($ph1ent['interface'], 0, 4) == "_vip") {
904
						$vpninterface = get_configured_vip_interface($ph1ent['interface']);
905
						$ifacesuse = get_real_interface($vpninterface);
906
					} else {
907
						$ifacesuse = get_failover_interface($ph1ent['interface']);
908
						if (substr($ifacesuse, 0, 4) == "_vip") {
909
							$vpninterface = get_configured_vip_interface($ifacesuse);
910
							$ifacesuse = get_real_interface($vpninterface);
911
						} else {
912
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
913
						}
914
					}
915

    
916
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
917
						$gatewayip = get_interface_gateway($vpninterface);
918
						$interfaceip = get_interface_ip($vpninterface);
919
						$subnet_bits = get_interface_subnet($vpninterface);
920
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
921
						/* if the remote gateway is in the local subnet, then don't add a route */
922
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
923
							if (is_ipaddrv4($gatewayip)) {
924
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
925
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
926
							}
927
						}
928
					}
929
				} else if ($ph1ent['protocol'] == 'inet6') {
930
					if (substr($ph1ent['interface'], 0, 4) == "_vip") {
931
						$vpninterface = get_configured_vip_interface($ph1ent['interface']);
932
						$ifacesuse = get_real_interface($vpninterface);
933
					} else {
934
						$ifacesuse = get_failover_interface($ph1ent['interface']);
935
						if (substr($ifacesuse, 0, 4) == "_vip") {
936
							$vpninterface = get_configured_vip_interface($ifacesuse);
937
							$ifacesuse = get_real_interface($vpninterface);
938
						} else {
939
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
940
						}
941
					}
942

    
943
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
944
						$gatewayip = get_interface_gateway_v6($vpninterface);
945
						$interfaceip = get_interface_ipv6($vpninterface);
946
						$subnet_bits = get_interface_subnetv6($vpninterface);
947
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
948
						/* if the remote gateway is in the local subnet, then don't add a route */
949
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
950
							if (is_ipaddrv6($gatewayip)) {
951
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
952
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
953
							}
954
						}
955
					}
956
				}
957
			}
958

    
959
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
960
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
961
				$myid_data = "{$myid_type}:{$myid_data}";
962
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
963
				if ($myid_data[0] == '#') {
964
				/* asn1dn needs double quotes */
965
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
966
				} else {
967
					$myid_data = "\"{$myid_data}\"";
968
				}
969
			}
970
			$leftid = '';
971
			if (!empty($myid_data)) {
972
				$leftid = "leftid = {$myid_data}";
973
			}
974

    
975
			$peerid_spec = '';
976
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
977
				// Only specify peer ID if we are not dealing with mobile PSK
978
			} else {
979
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
980
				if ($peerid_type == 'any') {
981
					$peerid_spec = '';
982
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
983
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
984
				} elseif ($peerid_type == "asn1dn") {
985
					/* asn1dn needs double quotes */
986
					if ($peerid_data[0] == '#') {
987
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
988
					} elseif (!empty($peerid_data)) {
989
						$peerid_spec = "\"{$peerid_data}\"";
990
					}
991
				} else {
992
					$peerid_spec = $peerid_data;
993
				}
994
			}
995

    
996
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
997
				$ealgosp1 = '';
998
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
999
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
1000
				if ($ealg_kl) {
1001
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
1002
				} else {
1003
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
1004
				}
1005

    
1006
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
1007
				if (!empty($modp)) {
1008
					$ealgosp1 .= "-{$modp}";
1009
				}
1010

    
1011
				$ealgosp1 .= "!";
1012
			}
1013

    
1014
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
1015
				if ($passive == "route") {
1016
					$dpdline = "dpdaction = restart";
1017
				} else {
1018
					$dpdline = "dpdaction = clear";
1019
				}
1020
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
1021
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
1022
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
1023
			} else {
1024
				$dpdline = "dpdaction = none";
1025
			}
1026

    
1027
			$ikelifeline = '';
1028
			if ($ph1ent['lifetime']) {
1029
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1030
			}
1031

    
1032
			$rightsourceip = NULL;
1033
			if (isset($ph1ent['mobile'])) {
1034
				$rightsourceips = array();
1035
				if (!empty($a_client['pool_address'])) {
1036
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1037
				}
1038
				if (!empty($a_client['pool_address_v6'])) {
1039
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1040
				}
1041
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1042
					$rightsourceips[] = "%radius";
1043
				}
1044
				if (count($rightsourceips)) {
1045
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1046
				}
1047
			}
1048

    
1049
			if (!empty($ph1ent['caref'])) {
1050
				$ca = lookup_ca($ph1ent['caref']);
1051
				if ($ca) {
1052
					$casubarr = cert_get_subject_array($ca['crt']);
1053
					$casub = "";
1054
					foreach ($casubarr as $casubfield) {
1055
						if (empty($casub)) {
1056
							$casub = "/";
1057
						}
1058
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
1059
					}
1060

    
1061
				}
1062
			}
1063

    
1064
			$authentication = "";
1065
			switch ($ph1ent['authentication_method']) {
1066
				case 'eap-mschapv2':
1067
					if (isset($ph1ent['mobile'])) {
1068
						$authentication = "eap_identity=%any\n\t";
1069
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1070
						if (!empty($ph1ent['certref'])) {
1071
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1072
							$authentication .= "\n\tleftsendcert=always";
1073
						}
1074
					}
1075
					break;
1076
				case 'eap-tls':
1077
					if (isset($ph1ent['mobile'])) {
1078
						$authentication = "eap_identity=%identity\n\t";
1079
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1080
						if (!empty($ph1ent['certref'])) {
1081
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1082
							$authentication .= "\n\tleftsendcert=always";
1083
						}
1084
					} else {
1085
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1086
						if (!empty($ph1ent['certref'])) {
1087
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1088
							$authentication .= "\n\tleftsendcert=always";
1089
						}
1090
					}
1091
					if (isset($casub)) {
1092
						$authentication .= "\n\trightca=\"$casub\"";
1093
					}
1094
					break;
1095
				case 'eap-radius':
1096
					if (isset($ph1ent['mobile'])) {
1097
						$authentication = "eap_identity=%identity\n\t";
1098
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1099
						if (!empty($ph1ent['certref'])) {
1100
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1101
							$authentication .= "\n\tleftsendcert=always";
1102
						}
1103
					} else {
1104
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1105
						if (!empty($ph1ent['certref'])) {
1106
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1107
							$authentication .= "\n\tleftsendcert=always";
1108
						}
1109
					}
1110
					break;
1111
				case 'xauth_rsa_server':
1112
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1113
					$authentication .= "\n\trightauth2 = xauth-generic";
1114
					if (!empty($ph1ent['certref'])) {
1115
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1116
						$authentication .= "\n\tleftsendcert=always";
1117
					}
1118
					if (isset($casub)) {
1119
						$authentication .= "\n\trightca=\"$casub\"";
1120
					}
1121
					break;
1122
				case 'xauth_psk_server':
1123
					$authentication = "leftauth = psk\n\trightauth = psk";
1124
					$authentication .= "\n\trightauth2 = xauth-generic";
1125
					break;
1126
				case 'pre_shared_key':
1127
					$authentication = "leftauth = psk\n\trightauth = psk";
1128
					break;
1129
				case 'rsasig':
1130
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1131
					if (!empty($ph1ent['certref'])) {
1132
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1133
						$authentication .= "\n\tleftsendcert=always";
1134
					}
1135
					if (isset($casub)) {
1136
						$authentication .= "\n\trightca=\"$casub\"";
1137
					}
1138
					break;
1139
				case 'hybrid_rsa_server':
1140
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1141
					if (!empty($ph1ent['certref'])) {
1142
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1143
						$authentication .= "\n\tleftsendcert=always";
1144
					}
1145
					break;
1146
			}
1147

    
1148
			$left_spec = $ep;
1149

    
1150
			if (isset($ph1ent['reauth_enable'])) {
1151
				$reauth = "reauth = no";
1152
			} else {
1153
				$reauth = "reauth = yes";
1154
			}
1155
			if (isset($ph1ent['rekey_enable'])) {
1156
				$rekey = "rekey = no";
1157
			} else {
1158
				$rekey = "rekey = yes";
1159
			}
1160

    
1161
			if ($ph1ent['nat_traversal'] == 'off') {
1162
				$forceencaps = 'forceencaps = no';
1163
			} else if ($ph1ent['nat_traversal'] == 'force') {
1164
				$forceencaps = 'forceencaps = yes';
1165
			} else {
1166
				$forceencaps = 'forceencaps = no';
1167
			}
1168

    
1169
			if ($ph1ent['mobike'] == 'on') {
1170
				$mobike = 'mobike = yes';
1171
			} else {
1172
				$mobike = 'mobike = no';
1173
			}
1174

    
1175
			if (isset($ph1ent['tfc_enable'])) {
1176
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1177
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1178
				} else {
1179
					$tfc = "tfc = %mtu";
1180
				}
1181
			}
1182

    
1183
			$ipseclifetime = 0;
1184
			$rightsubnet_spec = array();
1185
			$leftsubnet_spec = array();
1186
			$reqids = array();
1187
			$ealgoAHsp2arr = array();
1188
			$ealgoESPsp2arr = array();
1189
			if (is_array($a_phase2) && count($a_phase2)) {
1190
				foreach ($a_phase2 as $ph2ent) {
1191
					if ($ikeid != $ph2ent['ikeid']) {
1192
						continue;
1193
					}
1194

    
1195
					if (isset($ph2ent['disabled'])) {
1196
						continue;
1197
					}
1198

    
1199
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1200
						continue;
1201
					}
1202

    
1203
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1204
						$tunneltype = "type = tunnel";
1205

    
1206
						$localid_type = $ph2ent['localid']['type'];
1207
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1208

    
1209
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1210
						if (($localid_type == "none" || $localid_type == "mobile") &&
1211
						    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1212
							$left_spec = '%any';
1213
						} else {
1214
							if ($localid_type != "address") {
1215
								$localid_type = "subnet";
1216
							}
1217
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1218
							if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1219
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1220
								continue;
1221
							}
1222
							if (!empty($ph2ent['natlocalid'])) {
1223
								$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1224
								if ($ph2ent['natlocalid']['type'] != "address") {
1225
									if (is_subnet($natleftsubnet_data)) {
1226
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1227
									}
1228
								} else {
1229
									if (is_ipaddr($natleftsubnet_data)) {
1230
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1231
									}
1232
								}
1233
								$natfilterrules = true;
1234
							}
1235
						}
1236

    
1237
						$leftsubnet_spec[] = $leftsubnet_data;
1238

    
1239
						if (!isset($ph2ent['mobile'])) {
1240
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1241
							$rightsubnet_spec[] = $tmpsubnet;
1242
						} else if (!empty($a_client['pool_address'])) {
1243
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1244
						}
1245
					} else {
1246
						$tunneltype = "type = transport";
1247

    
1248
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1249
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1250
						    isset($ph1ent['mobile'])) {
1251
							$left_spec = "%any";
1252
						} else {
1253
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1254
							$leftsubnet_spec[] = $tmpsubnet;
1255
						}
1256

    
1257
						if (!isset($ph2ent['mobile'])) {
1258
							$rightsubnet_spec[] = $right_spec;
1259
						}
1260
					}
1261

    
1262
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1263
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1264
					}
1265

    
1266
					if ($ph2ent['protocol'] == 'esp') {
1267
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1268
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1269
								$ealg_id = $ealg['name'];
1270
								$ealg_kl = $ealg['keylen'];
1271

    
1272
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
1273
									if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1274
										require("ipsec.inc");
1275
									}
1276
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1277
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1278
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1279
									/* XXX: in some cases where include ordering is suspect these variables
1280
									 * are somehow 0 and we enter this loop forever and timeout after 900
1281
									 * seconds wrecking bootup */
1282
									if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1283
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1284
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1285
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1286
													$halgo = str_replace('hmac_', '', $halgo);
1287
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1288
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1289
													if (!empty($modp)) {
1290
														$tmpealgo .= "-{$modp}";
1291
													}
1292
													$ealgoESPsp2arr[] = $tmpealgo;
1293
												}
1294
											} else {
1295
												$tmpealgo = "{$ealg_id}{$keylen}";
1296
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1297
												if (!empty($modp)) {
1298
													$tmpealgo .= "-{$modp}";
1299
												}
1300
												$ealgoESPsp2arr[] = $tmpealgo;
1301
											}
1302
										}
1303
									}
1304
								} else {
1305
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1306
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1307
											$halgo = str_replace('hmac_', '', $halgo);
1308
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1309
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1310
											if (!empty($modp)) {
1311
												$tmpealgo .= "-{$modp}";
1312
											}
1313
											$ealgoESPsp2arr[] = $tmpealgo;
1314
										}
1315
									} else {
1316
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
1317
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1318
										if (!empty($modp)) {
1319
											$tmpealgo .= "-{$modp}";
1320
										}
1321
										$ealgoESPsp2arr[] = $tmpealgo;
1322
									}
1323
								}
1324
							}
1325
						}
1326
					} else if ($ph2ent['protocol'] == 'ah') {
1327
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1328
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1329
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1330
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1331
								if (!empty($modp)) {
1332
									$tmpAHalgo = "-{$modp}";
1333
								}
1334
								$ealgoAHsp2arr[] = $tmpAHalgo;
1335
							}
1336
						}
1337
					}
1338

    
1339
					$reqids[] = $ph2ent['reqid'];
1340

    
1341
					if (!empty($ph2ent['lifetime'])) {
1342
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1343
							$ipseclifetime = intval($ph2ent['lifetime']);
1344
						}
1345
					}
1346

    
1347
				}
1348
			}
1349

    
1350
			$ipsecconnect =<<<EOD
1351
	fragmentation = yes
1352
	keyexchange = {$keyexchange}
1353
	{$reauth}
1354
	{$forceencaps}
1355
	{$mobike}
1356
	{$tfc}
1357
	{$rekey}
1358
	installpolicy = yes
1359
	{$tunneltype}
1360
	{$dpdline}
1361
	auto = {$passive}
1362
	left = {$left_spec}
1363
	right = {$right_spec}
1364
	{$leftid}
1365

    
1366
EOD;
1367

    
1368
			/* Disable ipcomp for now. redmine #6167
1369
			if (isset($config['ipsec']['compression'])) {
1370
				$ipsecconnect .= "\tcompress = yes\n";
1371
				$enablecompression = true;
1372
			} */
1373
			if (!empty($ikelifeline)) {
1374
				$ipsecconnect .= "\t{$ikelifeline}\n";
1375
			}
1376
			if ($ipseclifetime > 0) {
1377
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1378
			}
1379
			if (!empty($rightsourceip)) {
1380
				$ipsecconnect .= "{$rightsourceip}";
1381
			}
1382
			if (!empty($ealgosp1)) {
1383
				$ipsecconnect .= "\t{$ealgosp1}\n";
1384
			}
1385
			if (!empty($ealgoAHsp2arr)) {
1386
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1387
			}
1388
			if (!empty($ealgoESPsp2arr)) {
1389
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1390
			}
1391
			if (!empty($authentication)) {
1392
				$ipsecconnect .= "\t{$authentication}\n";
1393
			}
1394
			if (!empty($peerid_spec)) {
1395
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1396
			}
1397
			if ($keyexchange == 'ikev1') {
1398
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1399
			}
1400

    
1401
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1402
				if (!empty($rightsubnet_spec)) {
1403
					$ipsecfin = '';
1404
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1405
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1406
						//if (!empty($reqids[$idx])) {
1407
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1408
						//}
1409
						$ipsecfin .= $ipsecconnect;
1410
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1411
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1412
					}
1413
				} else {
1414
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1415
				}
1416
			} else {
1417
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1418
				//if (!empty($reqids[$idx])) {
1419
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1420
				//}
1421
				$ipsecfin .= $ipsecconnect;
1422
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1423
					$tempsubnets = array();
1424
					foreach ($rightsubnet_spec as $rightsubnet) {
1425
						$tempsubnets[$rightsubnet] = $rightsubnet;
1426
					}
1427
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1428
					unset($tempsubnets, $rightsubnet);
1429
				}
1430
				if (!empty($leftsubnet_spec)) {
1431
					$tempsubnets = array();
1432
					foreach ($leftsubnet_spec as $leftsubnet) {
1433
						$tempsubnets[$leftsubnet] = $leftsubnet;
1434
					}
1435
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1436
					unset($tempsubnets, $leftsubnet);
1437
				}
1438
			}
1439
			$ipsecconf .= $ipsecfin;
1440
			unset($ipsecfin);
1441
		}
1442
	}
1443

    
1444
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1445
	unset($ipsecconf);
1446
	/* end ipsec.conf */
1447

    
1448
	if ($enablecompression === true) {
1449
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1450
	} else {
1451
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1452
	}
1453

    
1454
	/* manage process */
1455
	if ($restart === true) {
1456
		mwexec("/usr/local/sbin/ipsec restart", false);
1457
	} else {
1458
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1459
			/* Update configuration changes */
1460
			/* Read secrets */
1461
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1462
			mwexec("/usr/local/sbin/ipsec reload", false);
1463
		} else {
1464
			mwexec("/usr/local/sbin/ipsec start", false);
1465
		}
1466
	}
1467

    
1468
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1469
	if ($ipsecpinghostsactive == true) {
1470
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1471
	}
1472

    
1473
	if ($natfilterrules == true) {
1474
		filter_configure();
1475
	}
1476
	/* start filterdns, if necessary */
1477
	if (count($filterdns_list) > 0) {
1478
		$interval = 60;
1479
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1480
			$interval = $ipseccfg['dns-interval'];
1481
		}
1482

    
1483
		$hostnames = "";
1484
		array_unique($filterdns_list);
1485
		foreach ($filterdns_list as $hostname) {
1486
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1487
		}
1488
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1489
		unset($hostnames);
1490

    
1491
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1492
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1493
		} else {
1494
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1495
		}
1496
	} else {
1497
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1498
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1499
	}
1500

    
1501
	if (platform_booting()) {
1502
		echo "done\n";
1503
	}
1504

    
1505
	unlock($ipsecstartlock);
1506
	return count($filterdns_list);
1507
}
1508

    
1509
/*
1510
 * Forcefully restart IPsec
1511
 * This is required for when dynamic interfaces reload
1512
 * For all other occasions the normal vpn_ipsec_configure()
1513
 * will gracefully reload the settings without restarting
1514
 */
1515
function vpn_ipsec_force_reload($interface = "") {
1516
	global $g, $config;
1517

    
1518
	if (!ipsec_enabled()) {
1519
		return;
1520
	}
1521

    
1522
	$ipseccfg = $config['ipsec'];
1523

    
1524
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1525
		$found = false;
1526
		foreach ($ipseccfg['phase1'] as $ipsec) {
1527
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1528
				$found = true;
1529
				break;
1530
			}
1531
		}
1532
		if (!$found) {
1533
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1534
			return;
1535
		}
1536
	}
1537

    
1538
	/* If we get this far then we need to take action. */
1539
	log_error(gettext("Forcefully reloading IPsec"));
1540
	vpn_ipsec_configure();
1541
}
1542

    
1543
/* master setup for vpn (mpd) */
1544
function vpn_setup() {
1545
	/* start pppoe server */
1546
	vpn_pppoes_configure();
1547

    
1548
	/* setup l2tp */
1549
	vpn_l2tp_configure();
1550
}
1551

    
1552
function vpn_netgraph_support() {
1553
	$iflist = get_configured_interface_list();
1554
	foreach ($iflist as $iface) {
1555
		$realif = get_real_interface($iface);
1556
		/* Get support for netgraph(4) from the nic */
1557
		$ifinfo = pfSense_get_interface_addresses($realif);
1558
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1559
			pfSense_ngctl_attach(".", $realif);
1560
		}
1561
	}
1562
}
1563

    
1564
function vpn_pppoes_configure() {
1565
	global $config;
1566

    
1567
	if (is_array($config['pppoes']['pppoe'])) {
1568
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1569
			vpn_pppoe_configure($pppoe);
1570
		}
1571
	}
1572
}
1573

    
1574
function vpn_pppoe_configure(&$pppoecfg) {
1575
	global $config, $g;
1576

    
1577
	$syscfg = $config['system'];
1578

    
1579
	/* create directory if it does not exist */
1580
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1581
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1582
	}
1583

    
1584
	if (platform_booting()) {
1585
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1586
			return 0;
1587
		}
1588

    
1589
		echo gettext("Configuring PPPoE Server service... ");
1590
	} else {
1591
		/* kill mpd */
1592
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1593

    
1594
		/* wait for process to die */
1595
		sleep(2);
1596

    
1597
	}
1598

    
1599
	switch ($pppoecfg['mode']) {
1600

    
1601
		case 'server':
1602

    
1603
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1604

    
1605
			if ($pppoecfg['paporchap'] == "chap") {
1606
				$paporchap = "set link enable chap";
1607
			} else {
1608
				$paporchap = "set link enable pap";
1609
			}
1610

    
1611
			/* write mpd.conf */
1612
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1613
			if (!$fd) {
1614
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1615
				return 1;
1616
			}
1617
			$mpdconf = "\n\n";
1618
			$mpdconf .= "poes:\n";
1619

    
1620
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1621
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1622
			}
1623

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

    
1626
				$clientip = ip_after($pppoecfg['remoteip'], $i);
1627

    
1628
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1629
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1630
				} else {
1631
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1632
				}
1633

    
1634
				$mpdconf .=<<<EOD
1635

    
1636
poes{$pppoecfg['pppoeid']}{$i}:
1637
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1638
	{$issue_ip_type}
1639
	load pppoe_standard
1640

    
1641
EOD;
1642
			}
1643
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1644
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1645
			} else {
1646
				$pppoemaxlogins = 1;
1647
			}
1648

    
1649
			$mpdconf .=<<<EOD
1650

    
1651
pppoe_standard:
1652
	set bundle no multilink
1653
	set bundle enable compression
1654
	set auth max-logins {$pppoemaxlogins}
1655
	set iface up-script /usr/local/sbin/vpn-linkup
1656
	set iface down-script /usr/local/sbin/vpn-linkdown
1657
	set iface idle 0
1658
	set iface disable on-demand
1659
	set iface disable proxy-arp
1660
	set iface enable tcpmssfix
1661
	set iface mtu 1500
1662
	set link no pap chap
1663
	{$paporchap}
1664
	set link keep-alive 60 180
1665
	set ipcp yes vjcomp
1666
	set ipcp no vjcomp
1667
	set link max-redial -1
1668
	set link mtu 1492
1669
	set link mru 1492
1670
	set ccp yes mpp-e40
1671
	set ccp yes mpp-e128
1672
	set ccp yes mpp-stateless
1673
	set link latency 1
1674
	#set ipcp dns 10.10.1.3
1675
	#set bundle accept encryption
1676

    
1677
EOD;
1678

    
1679
			if (!empty($pppoecfg['dns1'])) {
1680
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1681
				if (!empty($pppoecfg['dns2'])) {
1682
					$mpdconf .= " " . $pppoecfg['dns2'];
1683
				}
1684
				$mpdconf .= "\n";
1685
			} elseif (isset ($config['dnsmasq']['enable'])) {
1686
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1687
				if ($syscfg['dnsserver'][0]) {
1688
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1689
				}
1690
				$mpdconf .= "\n";
1691
			} elseif (isset ($config['unbound']['enable'])) {
1692
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1693
				if ($syscfg['dnsserver'][0]) {
1694
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1695
				}
1696
				$mpdconf .= "\n";
1697
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1698
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1699
			}
1700

    
1701
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1702
				$radiusport = "";
1703
				$radiusacctport = "";
1704
				if (isset($pppoecfg['radius']['server']['port'])) {
1705
					$radiusport = $pppoecfg['radius']['server']['port'];
1706
				}
1707
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1708
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1709
				}
1710
				$mpdconf .=<<<EOD
1711
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1712
	set radius retries 3
1713
	set radius timeout 10
1714
	set auth enable radius-auth
1715

    
1716
EOD;
1717

    
1718
				if (isset ($pppoecfg['radius']['accounting'])) {
1719
					$mpdconf .=<<<EOD
1720
	set auth enable radius-acct
1721

    
1722
EOD;
1723
				}
1724
				if (isset($pppoecfg['radius']['nasip'])) {
1725
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1726
				}
1727
			}
1728

    
1729
			fwrite($fd, $mpdconf);
1730
			fclose($fd);
1731
			unset($mpdconf);
1732

    
1733
			/* write mpd.links */
1734
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1735
			if (!$fd) {
1736
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1737
				return 1;
1738
			}
1739

    
1740
			$mpdlinks = "";
1741

    
1742
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1743
				$mpdlinks .=<<<EOD
1744

    
1745
poes{$pppoecfg['pppoeid']}{$i}:
1746
	set phys type pppoe
1747
	set pppoe iface {$pppoe_interface}
1748
	set pppoe service "*"
1749
	set pppoe disable originate
1750
	set pppoe enable incoming
1751

    
1752
EOD;
1753
			}
1754

    
1755
			fwrite($fd, $mpdlinks);
1756
			fclose($fd);
1757
			unset($mpdlinks);
1758

    
1759
			if ($pppoecfg['username']) {
1760
				/* write mpd.secret */
1761
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1762
				if (!$fd) {
1763
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1764
					return 1;
1765
				}
1766

    
1767
				$mpdsecret = "\n\n";
1768

    
1769
				if (!empty($pppoecfg['username'])) {
1770
					$item = explode(" ", $pppoecfg['username']);
1771
					foreach ($item as $userdata) {
1772
						$data = explode(":", $userdata);
1773
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1774
					}
1775
				}
1776

    
1777
				fwrite($fd, $mpdsecret);
1778
				fclose($fd);
1779
				unset($mpdsecret);
1780
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1781
			}
1782

    
1783
			/* Check if previous instance is still up */
1784
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1785
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1786
			}
1787

    
1788
			/* Get support for netgraph(4) from the nic */
1789
			pfSense_ngctl_attach(".", $pppoe_interface);
1790
			/* fire up mpd */
1791
			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");
1792

    
1793
			break;
1794
	}
1795

    
1796
	if (platform_booting()) {
1797
		echo gettext("done") . "\n";
1798
	}
1799

    
1800
	return 0;
1801
}
1802

    
1803
function vpn_l2tp_configure() {
1804
	global $config, $g;
1805

    
1806
	$syscfg = $config['system'];
1807
	$l2tpcfg = $config['l2tp'];
1808

    
1809
	/* create directory if it does not exist */
1810
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1811
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1812
	}
1813

    
1814
	if (platform_booting()) {
1815
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1816
			return 0;
1817
		}
1818

    
1819
		echo gettext("Configuring l2tp VPN service... ");
1820
	} else {
1821
		/* kill mpd */
1822
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1823

    
1824
		/* wait for process to die */
1825
		sleep(8);
1826

    
1827
	}
1828

    
1829
	/* make sure l2tp-vpn directory exists */
1830
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1831
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1832
	}
1833

    
1834
	switch ($l2tpcfg['mode']) {
1835

    
1836
		case 'server':
1837
			$l2tp_listen="";
1838
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1839
			if (is_ipaddrv4($ipaddr)) {
1840
				$l2tp_listen="set l2tp self $ipaddr";
1841
			}
1842

    
1843
			switch ($l2tpcfg['paporchap']) {
1844
				case 'chap':
1845
					$paporchap = "set link enable chap";
1846
					break;
1847
				case 'chap-msv2':
1848
					$paporchap = "set link enable chap-msv2";
1849
					break;
1850
				default:
1851
					$paporchap = "set link enable pap";
1852
					break;
1853
			}
1854

    
1855
			/* write mpd.conf */
1856
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1857
			if (!$fd) {
1858
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1859
				return 1;
1860
			}
1861
			$mpdconf = "\n\n";
1862
			$mpdconf .=<<<EOD
1863
l2tps:
1864

    
1865
EOD;
1866

    
1867
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1868
				$mpdconf .= "	load l2tp{$i}\n";
1869
			}
1870

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

    
1873
				$clientip = ip_after($l2tpcfg['remoteip'], $i);
1874

    
1875
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1876
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1877
				} else {
1878
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1879
				}
1880

    
1881
				$mpdconf .=<<<EOD
1882

    
1883
l2tp{$i}:
1884
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1885
	{$issue_ip_type}
1886
	load l2tp_standard
1887

    
1888
EOD;
1889
			}
1890

    
1891
			$mpdconf .=<<<EOD
1892

    
1893
l2tp_standard:
1894
	set bundle disable multilink
1895
	set bundle enable compression
1896
	set bundle yes crypt-reqd
1897
	set ipcp yes vjcomp
1898
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1899
	set ccp yes mppc
1900
	set iface disable on-demand
1901
	set iface enable proxy-arp
1902
	set iface up-script /usr/local/sbin/vpn-linkup
1903
	set iface down-script /usr/local/sbin/vpn-linkdown
1904
	set link yes acfcomp protocomp
1905
	set link no pap chap
1906
	{$paporchap}
1907
	{$l2tp_listen}
1908
	set link keep-alive 10 180
1909

    
1910
EOD;
1911

    
1912
			if (is_ipaddr($l2tpcfg['wins'])) {
1913
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1914
			}
1915
			if (is_ipaddr($l2tpcfg['dns1'])) {
1916
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1917
				if (is_ipaddr($l2tpcfg['dns2'])) {
1918
					$mpdconf .= " " . $l2tpcfg['dns2'];
1919
				}
1920
				$mpdconf .= "\n";
1921
			} elseif (isset ($config['dnsmasq']['enable'])) {
1922
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1923
				if ($syscfg['dnsserver'][0]) {
1924
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1925
				}
1926
				$mpdconf .= "\n";
1927
			} elseif (isset ($config['unbound']['enable'])) {
1928
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1929
				if ($syscfg['dnsserver'][0]) {
1930
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1931
				}
1932
				$mpdconf .= "\n";
1933
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1934
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1935
			}
1936

    
1937
			if (isset ($l2tpcfg['radius']['enable'])) {
1938
				$mpdconf .=<<<EOD
1939
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1940
	set radius retries 3
1941
	set radius timeout 10
1942
	set auth enable radius-auth
1943

    
1944
EOD;
1945

    
1946
				if (isset ($l2tpcfg['radius']['accounting'])) {
1947
					$mpdconf .=<<<EOD
1948
	set auth enable radius-acct
1949

    
1950
EOD;
1951
				}
1952
			}
1953

    
1954
			fwrite($fd, $mpdconf);
1955
			fclose($fd);
1956
			unset($mpdconf);
1957

    
1958
			/* write mpd.links */
1959
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1960
			if (!$fd) {
1961
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1962
				return 1;
1963
			}
1964

    
1965
			$mpdlinks = "";
1966

    
1967
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1968
				$mpdlinks .=<<<EOD
1969

    
1970
l2tp{$i}:
1971
	set link type l2tp
1972
	set l2tp enable incoming
1973
	set l2tp disable originate
1974

    
1975
EOD;
1976
				if (!empty($l2tpcfg['secret'])) {
1977
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1978
				}
1979
			}
1980

    
1981
			fwrite($fd, $mpdlinks);
1982
			fclose($fd);
1983
			unset($mpdlinks);
1984

    
1985
			/* write mpd.secret */
1986
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1987
			if (!$fd) {
1988
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1989
				return 1;
1990
			}
1991

    
1992
			$mpdsecret = "\n\n";
1993

    
1994
			if (is_array($l2tpcfg['user'])) {
1995
				foreach ($l2tpcfg['user'] as $user) {
1996
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1997
				}
1998
			}
1999

    
2000
			fwrite($fd, $mpdsecret);
2001
			fclose($fd);
2002
			unset($mpdsecret);
2003
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2004

    
2005
			vpn_netgraph_support();
2006

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

    
2010
			break;
2011

    
2012
		case 'redir':
2013
			break;
2014
	}
2015

    
2016
	if (platform_booting()) {
2017
		echo "done\n";
2018
	}
2019

    
2020
	return 0;
2021
}
2022

    
2023
?>
(57-57/65)