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
require_once("auth.inc");
62

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

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

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

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

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

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

    
89
	return $cfgtext;
90
}
91

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

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

    
150
	return $conversion;
151
}
152

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
456
	unset($stronconf);
457

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

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

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

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

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

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

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

    
513
EOD;
514

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

    
530
EOD;
531
		}
532
	}
533

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

    
545
EOD;
546
	}
547

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
673
	$pskconf = "";
674

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

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

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

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

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

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

    
705
				@chmod($certpath, 0600);
706

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

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

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

    
728
				$myid = trim($myid_data);
729

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
856
EOD;
857
				}
858
			}
859
		}
860

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1062
				}
1063
			}
1064

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

    
1149
			$left_spec = $ep;
1150

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

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

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

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

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

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

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

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

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

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

    
1238
						$leftsubnet_spec[] = $leftsubnet_data;
1239

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

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

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

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

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

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

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

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

    
1348
				}
1349
			}
1350

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

    
1367
EOD;
1368

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1598
	}
1599

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

    
1602
		case 'server':
1603

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

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

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

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

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

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

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

    
1635
				$mpdconf .=<<<EOD
1636

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

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

    
1650
			$mpdconf .=<<<EOD
1651

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

    
1678
EOD;
1679

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

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

    
1717
EOD;
1718

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

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

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

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

    
1741
			$mpdlinks = "";
1742

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

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

    
1753
EOD;
1754
			}
1755

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

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

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

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

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

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

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

    
1794
			break;
1795
	}
1796

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

    
1801
	return 0;
1802
}
1803

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

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

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

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

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

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

    
1828
	}
1829

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

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

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

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

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

    
1866
EOD;
1867

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

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

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

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

    
1882
				$mpdconf .=<<<EOD
1883

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

    
1889
EOD;
1890
			}
1891

    
1892
			$mpdconf .=<<<EOD
1893

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

    
1911
EOD;
1912

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

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

    
1945
EOD;
1946

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

    
1951
EOD;
1952
				}
1953
			}
1954

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

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

    
1966
			$mpdlinks = "";
1967

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

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

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

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

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

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

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

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

    
2006
			vpn_netgraph_support();
2007

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

    
2011
			break;
2012

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

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

    
2021
	return 0;
2022
}
2023

    
2024
?>
(57-57/65)