Project

General

Profile

Download (58.2 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
	/* get the automatic ping_hosts.sh ready */
156
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
157
	touch("{$g['vardb_path']}/ipsecpinghosts");
158
	$ipsecpinghostsactive = false;
159

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

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

    
171
		/* wait for process to die */
172
		sleep(2);
173

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

    
177
		return 0;
178
	}
179

    
180
	$a_phase1 = $config['ipsec']['phase1'];
181
	$a_phase2 = $config['ipsec']['phase2'];
182
	$a_client = $config['ipsec']['client'];
183

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

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

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

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

    
270
	if (platform_booting()) {
271
		echo gettext("Configuring IPsec VPN... ");
272
	}
273

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

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

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

    
304
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
305
				$aggressive_mode_psk = true;
306
			}
307

    
308
			$ikeid = $ph1ent['ikeid'];
309

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

    
316
			if (!in_array($ep, $ipmap)) {
317
				$ipmap[] = $ep;
318
			}
319

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

    
323
			if (isset ($ph1ent['mobile'])) {
324
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
325
				continue;
326
			}
327

    
328
			$rg = $ph1ent['remote-gateway'];
329

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

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

    
353
					if ($ikeid != $ph2ent['ikeid']) {
354
						continue;
355
					}
356

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

    
416
	$accept_unencrypted = "";
417
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
418
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
419
	}
420

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

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

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

    
437
	$makebeforebreak = '';
438
	if (isset($config['ipsec']['makebeforebreak'])) {
439
		$makebeforebreak = 'make_before_break = yes';
440
	}
441

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

    
452
	unset($stronconf);
453

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

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

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

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

    
497
	plugins {
498
		# Load defaults
499
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
500

    
501
		stroke {
502
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
503
		}
504

    
505
		unity {
506
			load = {$unity_enabled}
507
		}
508

    
509
EOD;
510

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

    
526
EOD;
527
		}
528
	}
529

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

    
541
EOD;
542
	}
543

    
544
	if (is_array($a_client) && isset($a_client['enable'])) {
545
		$strongswan .= "\t\tattr {\n";
546

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

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

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

    
584
				if (!isset($ph2ent['mobile'])) {
585
					continue;
586
				}
587

    
588
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
589

    
590
				if (!empty($net_list)) {
591
					$net_list .= ",";
592
				}
593
				$net_list .= $localid;
594
			}
595

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

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

    
612
		if (!empty($a_client['dns_split'])) {
613
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
614
		}
615

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

    
620
		if (isset($a_client['save_passwd'])) {
621
			$strongswan .= "\t\t\t28673 = 1\n";
622
		}
623

    
624
		if ($a_client['pfs_group']) {
625
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
626
		}
627
		$strongswan .= "\t\t}\n";
628

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

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

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

    
669
	$pskconf = "";
670

    
671
	$vpncas = array();
672
	if (is_array($a_phase1) && count($a_phase1)) {
673
		foreach ($a_phase1 as $ph1ent) {
674

    
675
			if (isset($ph1ent['disabled'])) {
676
				continue;
677
			}
678

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

    
683
				$ikeid = $ph1ent['ikeid'];
684
				$cert = lookup_cert($ph1ent['certref']);
685

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

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

    
701
				@chmod($certpath, 0600);
702

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

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

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

    
724
				$myid = trim($myid_data);
725

    
726
				if (empty($peerid_data)) {
727
					continue;
728
				}
729

    
730
				if ($myid_type == 'fqdn' && !empty($myid)) {
731
					$myid = "@{$myid}";
732
				}
733

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

    
736
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
737

    
738
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
739
					$peerid = "@{$peerid}";
740
				}
741

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

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

    
756
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
757
					$thisca = lookup_ca($ph1ent['caref']);
758
					$vpncas[$ph1ent['caref']] = $thisca;
759

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

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

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

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

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

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

    
830
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
831
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
832

    
833
		if (isset($config['ipsec']['strictcrlpolicy'])) {
834
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
835
		}
836

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

    
845
conn bypasslan
846
	leftsubnet = {$lansa}/{$lansn}
847
	rightsubnet = {$lansa}/{$lansn}
848
	authby = never
849
	type = passthrough
850
	auto = route
851

    
852
EOD;
853
				}
854
			}
855
		}
856

    
857
		foreach ($a_phase1 as $ph1ent) {
858
			if (isset($ph1ent['disabled'])) {
859
				continue;
860
			}
861

    
862
			if ($ph1ent['mode'] == "aggressive") {
863
				$aggressive = "yes";
864
			} else {
865
				$aggressive = "no";
866
			}
867

    
868
			$ep = ipsec_get_phase1_src($ph1ent);
869
			if (!$ep) {
870
				continue;
871
			}
872

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

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

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

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

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

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

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

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

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

    
1003
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
1004
				if (!empty($modp)) {
1005
					$ealgosp1 .= "-{$modp}";
1006
				}
1007

    
1008
				$ealgosp1 .= "!";
1009
			}
1010

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

    
1024
			$ikelifeline = '';
1025
			if ($ph1ent['lifetime']) {
1026
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1027
			}
1028

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

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

    
1058
				}
1059
			}
1060

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

    
1142
			$left_spec = $ep;
1143

    
1144
			if (isset($ph1ent['reauth_enable'])) {
1145
				$reauth = "reauth = no";
1146
			} else {
1147
				$reauth = "reauth = yes";
1148
			}
1149
			if (isset($ph1ent['rekey_enable'])) {
1150
				$rekey = "rekey = no";
1151
			} else {
1152
				$rekey = "rekey = yes";
1153
			}
1154

    
1155
			if ($ph1ent['nat_traversal'] == 'off') {
1156
				$forceencaps = 'forceencaps = no';
1157
			} else if ($ph1ent['nat_traversal'] == 'force') {
1158
				$forceencaps = 'forceencaps = yes';
1159
			} else {
1160
				$forceencaps = 'forceencaps = no';
1161
			}
1162

    
1163
			if ($ph1ent['mobike'] == 'on') {
1164
				$mobike = 'mobike = yes';
1165
			} else {
1166
				$mobike = 'mobike = no';
1167
			}
1168

    
1169
			if (isset($ph1ent['tfc_enable'])) {
1170
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1171
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1172
				} else {
1173
					$tfc = "tfc = %mtu";
1174
				}
1175
			}
1176

    
1177
			$ipseclifetime = 0;
1178
			$rightsubnet_spec = array();
1179
			$leftsubnet_spec = array();
1180
			$reqids = array();
1181
			$ealgoAHsp2arr = array();
1182
			$ealgoESPsp2arr = array();
1183
			if (is_array($a_phase2) && count($a_phase2)) {
1184
				foreach ($a_phase2 as $ph2ent) {
1185
					if ($ikeid != $ph2ent['ikeid']) {
1186
						continue;
1187
					}
1188

    
1189
					if (isset($ph2ent['disabled'])) {
1190
						continue;
1191
					}
1192

    
1193
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1194
						continue;
1195
					}
1196

    
1197
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1198
						$tunneltype = "type = tunnel";
1199

    
1200
						$localid_type = $ph2ent['localid']['type'];
1201
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1202

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

    
1231
						$leftsubnet_spec[] = $leftsubnet_data;
1232

    
1233
						if (!isset($ph2ent['mobile'])) {
1234
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1235
							$rightsubnet_spec[] = $tmpsubnet;
1236
						} else if (!empty($a_client['pool_address'])) {
1237
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1238
						}
1239
					} else {
1240
						$tunneltype = "type = transport";
1241

    
1242
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1243
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1244
						    isset($ph1ent['mobile'])) {
1245
							$left_spec = "%any";
1246
						} else {
1247
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1248
							$leftsubnet_spec[] = $tmpsubnet;
1249
						}
1250

    
1251
						if (!isset($ph2ent['mobile'])) {
1252
							$rightsubnet_spec[] = $right_spec;
1253
						}
1254
					}
1255

    
1256
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1257
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1258
					}
1259

    
1260
					if ($ph2ent['protocol'] == 'esp') {
1261
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1262
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1263
								$ealg_id = $ealg['name'];
1264
								$ealg_kl = $ealg['keylen'];
1265

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

    
1333
					$reqids[] = $ph2ent['reqid'];
1334

    
1335
					if (!empty($ph2ent['lifetime'])) {
1336
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1337
							$ipseclifetime = intval($ph2ent['lifetime']);
1338
						}
1339
					}
1340

    
1341
				}
1342
			}
1343

    
1344
			$ipsecconnect =<<<EOD
1345
	fragmentation = yes
1346
	keyexchange = {$keyexchange}
1347
	{$reauth}
1348
	{$forceencaps}
1349
	{$mobike}
1350
	{$tfc}
1351
	{$rekey}
1352
	installpolicy = yes
1353
	{$tunneltype}
1354
	{$dpdline}
1355
	auto = {$passive}
1356
	left = {$left_spec}
1357
	right = {$right_spec}
1358
	{$leftid}
1359

    
1360
EOD;
1361

    
1362
			if (isset($config['ipsec']['compression'])) {
1363
				$ipsecconnect .= "\tcompress = yes\n";
1364
				$enablecompression = true;
1365
			}
1366
			if (!empty($ikelifeline)) {
1367
				$ipsecconnect .= "\t{$ikelifeline}\n";
1368
			}
1369
			if ($ipseclifetime > 0) {
1370
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1371
			}
1372
			if (!empty($rightsourceip)) {
1373
				$ipsecconnect .= "{$rightsourceip}";
1374
			}
1375
			if (!empty($ealgosp1)) {
1376
				$ipsecconnect .= "\t{$ealgosp1}\n";
1377
			}
1378
			if (!empty($ealgoAHsp2arr)) {
1379
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1380
			}
1381
			if (!empty($ealgoESPsp2arr)) {
1382
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1383
			}
1384
			if (!empty($authentication)) {
1385
				$ipsecconnect .= "\t{$authentication}\n";
1386
			}
1387
			if (!empty($peerid_spec)) {
1388
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1389
			}
1390
			if ($keyexchange == 'ikev1') {
1391
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1392
			}
1393

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

    
1437
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1438
	unset($ipsecconf);
1439
	/* end ipsec.conf */
1440

    
1441
	if ($enablecompression === true) {
1442
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1443
	} else {
1444
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1445
	}
1446

    
1447
	/* manage process */
1448
	if ($restart === true) {
1449
		mwexec("/usr/local/sbin/ipsec restart", false);
1450
	} else {
1451
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1452
			/* Update configuration changes */
1453
			/* Read secrets */
1454
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1455
			mwexec("/usr/local/sbin/ipsec reload", false);
1456
		} else {
1457
			mwexec("/usr/local/sbin/ipsec start", false);
1458
		}
1459
	}
1460

    
1461
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1462
	if ($ipsecpinghostsactive == true) {
1463
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1464
	}
1465

    
1466
	if ($natfilterrules == true) {
1467
		filter_configure();
1468
	}
1469
	/* start filterdns, if necessary */
1470
	if (count($filterdns_list) > 0) {
1471
		$interval = 60;
1472
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1473
			$interval = $ipseccfg['dns-interval'];
1474
		}
1475

    
1476
		$hostnames = "";
1477
		array_unique($filterdns_list);
1478
		foreach ($filterdns_list as $hostname) {
1479
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1480
		}
1481
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1482
		unset($hostnames);
1483

    
1484
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1485
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1486
		} else {
1487
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1488
		}
1489
	} else {
1490
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1491
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1492
	}
1493

    
1494
	if (platform_booting()) {
1495
		echo "done\n";
1496
	}
1497

    
1498
	return count($filterdns_list);
1499
}
1500

    
1501
/*
1502
 * Forcefully restart IPsec
1503
 * This is required for when dynamic interfaces reload
1504
 * For all other occasions the normal vpn_ipsec_configure()
1505
 * will gracefully reload the settings without restarting
1506
 */
1507
function vpn_ipsec_force_reload($interface = "") {
1508
	global $g, $config;
1509

    
1510
	if (!ipsec_enabled()) {
1511
		return;
1512
	}
1513

    
1514
	$ipseccfg = $config['ipsec'];
1515

    
1516
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1517
		$found = false;
1518
		foreach ($ipseccfg['phase1'] as $ipsec) {
1519
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1520
				$found = true;
1521
				break;
1522
			}
1523
		}
1524
		if (!$found) {
1525
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1526
			return;
1527
		}
1528
	}
1529

    
1530
	/* If we get this far then we need to take action. */
1531
	log_error(gettext("Forcefully reloading IPsec"));
1532
	vpn_ipsec_configure();
1533
}
1534

    
1535
/* master setup for vpn (mpd) */
1536
function vpn_setup() {
1537
	/* start pppoe server */
1538
	vpn_pppoes_configure();
1539

    
1540
	/* setup l2tp */
1541
	vpn_l2tp_configure();
1542
}
1543

    
1544
function vpn_netgraph_support() {
1545
	$iflist = get_configured_interface_list();
1546
	foreach ($iflist as $iface) {
1547
		$realif = get_real_interface($iface);
1548
		/* Get support for netgraph(4) from the nic */
1549
		$ifinfo = pfSense_get_interface_addresses($realif);
1550
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1551
			pfSense_ngctl_attach(".", $realif);
1552
		}
1553
	}
1554
}
1555

    
1556
function vpn_pppoes_configure() {
1557
	global $config;
1558

    
1559
	if (is_array($config['pppoes']['pppoe'])) {
1560
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1561
			vpn_pppoe_configure($pppoe);
1562
		}
1563
	}
1564
}
1565

    
1566
function vpn_pppoe_configure(&$pppoecfg) {
1567
	global $config, $g;
1568

    
1569
	$syscfg = $config['system'];
1570

    
1571
	/* create directory if it does not exist */
1572
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1573
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1574
	}
1575

    
1576
	if (platform_booting()) {
1577
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1578
			return 0;
1579
		}
1580

    
1581
		echo gettext("Configuring PPPoE Server service... ");
1582
	} else {
1583
		/* kill mpd */
1584
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1585

    
1586
		/* wait for process to die */
1587
		sleep(2);
1588

    
1589
	}
1590

    
1591
	switch ($pppoecfg['mode']) {
1592

    
1593
		case 'server':
1594

    
1595
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1596

    
1597
			if ($pppoecfg['paporchap'] == "chap") {
1598
				$paporchap = "set link enable chap";
1599
			} else {
1600
				$paporchap = "set link enable pap";
1601
			}
1602

    
1603
			/* write mpd.conf */
1604
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1605
			if (!$fd) {
1606
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1607
				return 1;
1608
			}
1609
			$mpdconf = "\n\n";
1610
			$mpdconf .= "poes:\n";
1611

    
1612
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1613
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1614
			}
1615

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

    
1618
				$clientip = ip_after($pppoecfg['remoteip'], $i);
1619

    
1620
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1621
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1622
				} else {
1623
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1624
				}
1625

    
1626
				$mpdconf .=<<<EOD
1627

    
1628
poes{$pppoecfg['pppoeid']}{$i}:
1629
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1630
	{$issue_ip_type}
1631
	load pppoe_standard
1632

    
1633
EOD;
1634
			}
1635
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1636
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1637
			} else {
1638
				$pppoemaxlogins = 1;
1639
			}
1640

    
1641
			$mpdconf .=<<<EOD
1642

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

    
1669
EOD;
1670

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

    
1693
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1694
				$radiusport = "";
1695
				$radiusacctport = "";
1696
				if (isset($pppoecfg['radius']['server']['port'])) {
1697
					$radiusport = $pppoecfg['radius']['server']['port'];
1698
				}
1699
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1700
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1701
				}
1702
				$mpdconf .=<<<EOD
1703
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1704
	set radius retries 3
1705
	set radius timeout 10
1706
	set auth enable radius-auth
1707

    
1708
EOD;
1709

    
1710
				if (isset ($pppoecfg['radius']['accounting'])) {
1711
					$mpdconf .=<<<EOD
1712
	set auth enable radius-acct
1713

    
1714
EOD;
1715
				}
1716
				if (isset($pppoecfg['radius']['nasip'])) {
1717
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1718
				}
1719
			}
1720

    
1721
			fwrite($fd, $mpdconf);
1722
			fclose($fd);
1723
			unset($mpdconf);
1724

    
1725
			/* write mpd.links */
1726
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1727
			if (!$fd) {
1728
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1729
				return 1;
1730
			}
1731

    
1732
			$mpdlinks = "";
1733

    
1734
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1735
				$mpdlinks .=<<<EOD
1736

    
1737
poes{$pppoecfg['pppoeid']}{$i}:
1738
	set phys type pppoe
1739
	set pppoe iface {$pppoe_interface}
1740
	set pppoe service "*"
1741
	set pppoe disable originate
1742
	set pppoe enable incoming
1743

    
1744
EOD;
1745
			}
1746

    
1747
			fwrite($fd, $mpdlinks);
1748
			fclose($fd);
1749
			unset($mpdlinks);
1750

    
1751
			if ($pppoecfg['username']) {
1752
				/* write mpd.secret */
1753
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1754
				if (!$fd) {
1755
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1756
					return 1;
1757
				}
1758

    
1759
				$mpdsecret = "\n\n";
1760

    
1761
				if (!empty($pppoecfg['username'])) {
1762
					$item = explode(" ", $pppoecfg['username']);
1763
					foreach ($item as $userdata) {
1764
						$data = explode(":", $userdata);
1765
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1766
					}
1767
				}
1768

    
1769
				fwrite($fd, $mpdsecret);
1770
				fclose($fd);
1771
				unset($mpdsecret);
1772
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1773
			}
1774

    
1775
			/* Check if previous instance is still up */
1776
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1777
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1778
			}
1779

    
1780
			/* Get support for netgraph(4) from the nic */
1781
			pfSense_ngctl_attach(".", $pppoe_interface);
1782
			/* fire up mpd */
1783
			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");
1784

    
1785
			break;
1786
	}
1787

    
1788
	if (platform_booting()) {
1789
		echo gettext("done") . "\n";
1790
	}
1791

    
1792
	return 0;
1793
}
1794

    
1795
function vpn_l2tp_configure() {
1796
	global $config, $g;
1797

    
1798
	$syscfg = $config['system'];
1799
	$l2tpcfg = $config['l2tp'];
1800

    
1801
	/* create directory if it does not exist */
1802
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1803
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1804
	}
1805

    
1806
	if (platform_booting()) {
1807
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1808
			return 0;
1809
		}
1810

    
1811
		echo gettext("Configuring l2tp VPN service... ");
1812
	} else {
1813
		/* kill mpd */
1814
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1815

    
1816
		/* wait for process to die */
1817
		sleep(8);
1818

    
1819
	}
1820

    
1821
	/* make sure l2tp-vpn directory exists */
1822
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1823
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1824
	}
1825

    
1826
	switch ($l2tpcfg['mode']) {
1827

    
1828
		case 'server':
1829
			$l2tp_listen="";
1830
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1831
			if (is_ipaddrv4($ipaddr)) {
1832
				$l2tp_listen="set l2tp self $ipaddr";
1833
			}
1834

    
1835
			switch ($l2tpcfg['paporchap']) {
1836
				case 'chap':
1837
					$paporchap = "set link enable chap";
1838
					break;
1839
				case 'chap-msv2':
1840
					$paporchap = "set link enable chap-msv2";
1841
					break;
1842
				default:
1843
					$paporchap = "set link enable pap";
1844
					break;
1845
			}
1846

    
1847
			/* write mpd.conf */
1848
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1849
			if (!$fd) {
1850
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1851
				return 1;
1852
			}
1853
			$mpdconf = "\n\n";
1854
			$mpdconf .=<<<EOD
1855
l2tps:
1856

    
1857
EOD;
1858

    
1859
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1860
				$mpdconf .= "	load l2tp{$i}\n";
1861
			}
1862

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

    
1865
				$clientip = ip_after($l2tpcfg['remoteip'], $i);
1866

    
1867
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1868
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1869
				} else {
1870
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1871
				}
1872

    
1873
				$mpdconf .=<<<EOD
1874

    
1875
l2tp{$i}:
1876
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1877
	{$issue_ip_type}
1878
	load l2tp_standard
1879

    
1880
EOD;
1881
			}
1882

    
1883
			$mpdconf .=<<<EOD
1884

    
1885
l2tp_standard:
1886
	set bundle disable multilink
1887
	set bundle enable compression
1888
	set bundle yes crypt-reqd
1889
	set ipcp yes vjcomp
1890
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1891
	set ccp yes mppc
1892
	set iface disable on-demand
1893
	set iface enable proxy-arp
1894
	set iface up-script /usr/local/sbin/vpn-linkup
1895
	set iface down-script /usr/local/sbin/vpn-linkdown
1896
	set link yes acfcomp protocomp
1897
	set link no pap chap
1898
	{$paporchap}
1899
	{$l2tp_listen}
1900
	set link keep-alive 10 180
1901

    
1902
EOD;
1903

    
1904
			if (is_ipaddr($l2tpcfg['wins'])) {
1905
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1906
			}
1907
			if (is_ipaddr($l2tpcfg['dns1'])) {
1908
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1909
				if (is_ipaddr($l2tpcfg['dns2'])) {
1910
					$mpdconf .= " " . $l2tpcfg['dns2'];
1911
				}
1912
				$mpdconf .= "\n";
1913
			} elseif (isset ($config['dnsmasq']['enable'])) {
1914
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1915
				if ($syscfg['dnsserver'][0]) {
1916
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1917
				}
1918
				$mpdconf .= "\n";
1919
			} elseif (isset ($config['unbound']['enable'])) {
1920
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1921
				if ($syscfg['dnsserver'][0]) {
1922
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1923
				}
1924
				$mpdconf .= "\n";
1925
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1926
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1927
			}
1928

    
1929
			if (isset ($l2tpcfg['radius']['enable'])) {
1930
				$mpdconf .=<<<EOD
1931
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1932
	set radius retries 3
1933
	set radius timeout 10
1934
	set auth enable radius-auth
1935

    
1936
EOD;
1937

    
1938
				if (isset ($l2tpcfg['radius']['accounting'])) {
1939
					$mpdconf .=<<<EOD
1940
	set auth enable radius-acct
1941

    
1942
EOD;
1943
				}
1944
			}
1945

    
1946
			fwrite($fd, $mpdconf);
1947
			fclose($fd);
1948
			unset($mpdconf);
1949

    
1950
			/* write mpd.links */
1951
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1952
			if (!$fd) {
1953
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1954
				return 1;
1955
			}
1956

    
1957
			$mpdlinks = "";
1958

    
1959
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1960
				$mpdlinks .=<<<EOD
1961

    
1962
l2tp{$i}:
1963
	set link type l2tp
1964
	set l2tp enable incoming
1965
	set l2tp disable originate
1966

    
1967
EOD;
1968
				if (!empty($l2tpcfg['secret'])) {
1969
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1970
				}
1971
			}
1972

    
1973
			fwrite($fd, $mpdlinks);
1974
			fclose($fd);
1975
			unset($mpdlinks);
1976

    
1977
			/* write mpd.secret */
1978
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1979
			if (!$fd) {
1980
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1981
				return 1;
1982
			}
1983

    
1984
			$mpdsecret = "\n\n";
1985

    
1986
			if (is_array($l2tpcfg['user'])) {
1987
				foreach ($l2tpcfg['user'] as $user) {
1988
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1989
				}
1990
			}
1991

    
1992
			fwrite($fd, $mpdsecret);
1993
			fclose($fd);
1994
			unset($mpdsecret);
1995
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1996

    
1997
			vpn_netgraph_support();
1998

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

    
2002
			break;
2003

    
2004
		case 'redir':
2005
			break;
2006
	}
2007

    
2008
	if (platform_booting()) {
2009
		echo "done\n";
2010
	}
2011

    
2012
	return 0;
2013
}
2014

    
2015
?>
(57-57/65)