Project

General

Profile

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

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
8
	All rights reserved.
9

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
88
	return $cfgtext;
89
}
90

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

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

    
149
	return $conversion;
150
}
151

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
429
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
430
	if ($aggressive_mode_psk) {
431
		log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
432
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
433
			$restart = true;
434
		}
435
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
436
	}
437

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

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

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

    
455
	unset($stronconf);
456

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

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

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

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

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

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

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

    
512
EOD;
513

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

    
529
EOD;
530
		}
531
	}
532

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

    
544
EOD;
545
	}
546

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
672
	$pskconf = "";
673

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

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

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

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

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

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

    
704
				@chmod($certpath, 0600);
705

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

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

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

    
727
				$myid = trim($myid_data);
728

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
855
EOD;
856
				}
857
			}
858
		}
859

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1061
				}
1062
			}
1063

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

    
1148
			$left_spec = $ep;
1149

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

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

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

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

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

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

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

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

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

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

    
1237
						$leftsubnet_spec[] = $leftsubnet_data;
1238

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

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

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

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

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

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

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

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

    
1347
				}
1348
			}
1349

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

    
1366
EOD;
1367

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1596
	}
1597

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

    
1600
		case 'server':
1601

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

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

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

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

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

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

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

    
1633
				$mpdconf .=<<<EOD
1634

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

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

    
1648
			$mpdconf .=<<<EOD
1649

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

    
1676
EOD;
1677

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

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

    
1715
EOD;
1716

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

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

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

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

    
1739
			$mpdlinks = "";
1740

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

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

    
1751
EOD;
1752
			}
1753

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

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

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

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

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

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

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

    
1792
			break;
1793
	}
1794

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

    
1799
	return 0;
1800
}
1801

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

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

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

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

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

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

    
1826
	}
1827

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

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

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

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

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

    
1864
EOD;
1865

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

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

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

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

    
1880
				$mpdconf .=<<<EOD
1881

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

    
1887
EOD;
1888
			}
1889

    
1890
			$mpdconf .=<<<EOD
1891

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

    
1909
EOD;
1910

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

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

    
1943
EOD;
1944

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

    
1949
EOD;
1950
				}
1951
			}
1952

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

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

    
1964
			$mpdlinks = "";
1965

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

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

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

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

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

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

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

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

    
2004
			vpn_netgraph_support();
2005

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

    
2009
			break;
2010

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

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

    
2019
	return 0;
2020
}
2021

    
2022
?>
(57-57/65)