Project

General

Profile

Download (58.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2008 Shrew Soft Inc
8
 * All rights reserved.
9
 *
10
 * originally part of m0n0wall (http://m0n0.ch/wall)
11
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
 * All rights reserved.
13
 *
14
 * Redistribution and use in source and binary forms, with or without
15
 * modification, are permitted provided that the following conditions are met:
16
 *
17
 * 1. Redistributions of source code must retain the above copyright notice,
18
 *    this list of conditions and the following disclaimer.
19
 *
20
 * 2. Redistributions in binary form must reproduce the above copyright
21
 *    notice, this list of conditions and the following disclaimer in
22
 *    the documentation and/or other materials provided with the
23
 *    distribution.
24
 *
25
 * 3. All advertising materials mentioning features or use of this software
26
 *    must display the following acknowledgment:
27
 *    "This product includes software developed by the pfSense Project
28
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
29
 *
30
 * 4. The names "pfSense" and "pfSense Project" must not be used to
31
 *    endorse or promote products derived from this software without
32
 *    prior written permission. For written permission, please contact
33
 *    coreteam@pfsense.org.
34
 *
35
 * 5. Products derived from this software may not be called "pfSense"
36
 *    nor may "pfSense" appear in their names without prior written
37
 *    permission of the Electric Sheep Fencing, LLC.
38
 *
39
 * 6. Redistributions of any form whatsoever must retain the following
40
 *    acknowledgment:
41
 *
42
 * "This product includes software developed by the pfSense Project
43
 * for use in the pfSense software distribution (http://www.pfsense.org/).
44
 *
45
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
 * OF THE POSSIBILITY OF SUCH DAMAGE.
57
 */
58

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

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

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

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

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

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

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

    
89
	return $cfgtext;
90
}
91

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

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

    
150
	return $conversion;
151
}
152

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
456
	unset($stronconf);
457

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

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

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

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

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

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

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

    
513
EOD;
514

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

    
530
EOD;
531
		}
532
	}
533

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

    
545
EOD;
546
	}
547

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
673
	$pskconf = "";
674

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

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

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

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

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

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

    
705
				@chmod($certpath, 0600);
706

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

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

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

    
728
				$myid = trim($myid_data);
729

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
856
EOD;
857
				}
858
			}
859
		}
860

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

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

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

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

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

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

    
903
				if (substr($ph1ent['interface'], 0, 4) == "_vip") {
904
					$vpninterface = get_configured_vip_interface($ph1ent['interface']);
905
					if (substr($vpninterface, 0, 4) == "_vip") {
906
						// vips are nested if its a ipalias with a carp parent
907
						$vpninterface = get_configured_vip_interface($vpninterface);
908
					}
909
					$ifacesuse = get_real_interface($vpninterface);
910
				} else {
911
					$ifacesuse = get_failover_interface($ph1ent['interface']);
912
					if (substr($ifacesuse, 0, 4) == "_vip") {
913
						$vpninterface = get_configured_vip_interface($ifacesuse);
914
						$ifacesuse = get_real_interface($vpninterface);
915
					} else {
916
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
917
					}
918
				}
919
				if ($ph1ent['protocol'] == 'inet') {
920
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
921
						$gatewayip = get_interface_gateway($vpninterface);
922
						$interfaceip = get_interface_ip($vpninterface);
923
						$subnet_bits = get_interface_subnet($vpninterface);
924
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
925
						/* if the remote gateway is in the local subnet, then don't add a route */
926
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
927
							if (is_ipaddrv4($gatewayip)) {
928
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
929
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
930
							}
931
						}
932
					}
933
				} else if ($ph1ent['protocol'] == 'inet6') {
934
					if (!empty($ifacesuse) && interface_has_gatewayv6($vpninterface)) {
935
						$gatewayip = get_interface_gateway_v6($vpninterface);
936
						$interfaceip = get_interface_ipv6($vpninterface);
937
						$subnet_bits = get_interface_subnetv6($vpninterface);
938
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
939
						/* if the remote gateway is in the local subnet, then don't add a route */
940
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
941
							if (is_ipaddrv6($gatewayip)) {
942
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
943
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
944
							}
945
						}
946
					}
947
				}
948
			}
949

    
950
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
951
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
952
				$myid_data = "{$myid_type}:{$myid_data}";
953
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
954
				if ($myid_data[0] == '#') {
955
				/* asn1dn needs double quotes */
956
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
957
				} else {
958
					$myid_data = "\"{$myid_data}\"";
959
				}
960
			}
961
			$leftid = '';
962
			if (!empty($myid_data)) {
963
				$leftid = "leftid = {$myid_data}";
964
			}
965

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

    
987
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
988
				$ealgosp1 = '';
989
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
990
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
991
				if ($ealg_kl) {
992
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
993
				} else {
994
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
995
				}
996

    
997
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
998
				if (!empty($modp)) {
999
					$ealgosp1 .= "-{$modp}";
1000
				}
1001

    
1002
				$ealgosp1 .= "!";
1003
			}
1004

    
1005
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
1006
				if ($passive == "route") {
1007
					$dpdline = "dpdaction = restart";
1008
				} else {
1009
					$dpdline = "dpdaction = clear";
1010
				}
1011
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
1012
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
1013
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
1014
			} else {
1015
				$dpdline = "dpdaction = none";
1016
			}
1017

    
1018
			$ikelifeline = '';
1019
			if ($ph1ent['lifetime']) {
1020
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1021
			}
1022

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

    
1040
			if (!empty($ph1ent['caref'])) {
1041
				$ca = lookup_ca($ph1ent['caref']);
1042
				if ($ca) {
1043
					$casubarr = cert_get_subject_array($ca['crt']);
1044
					$casub = "";
1045
					foreach ($casubarr as $casubfield) {
1046
						if (empty($casub)) {
1047
							$casub = "/";
1048
						}
1049
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
1050
					}
1051

    
1052
				}
1053
			}
1054

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

    
1139
			$left_spec = $ep;
1140

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

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

    
1160
			if ($ph1ent['mobike'] == 'on') {
1161
				$mobike = 'mobike = yes';
1162
			} else {
1163
				$mobike = 'mobike = no';
1164
			}
1165

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

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

    
1186
					if (isset($ph2ent['disabled'])) {
1187
						continue;
1188
					}
1189

    
1190
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1191
						continue;
1192
					}
1193

    
1194
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1195
						$tunneltype = "type = tunnel";
1196

    
1197
						$localid_type = $ph2ent['localid']['type'];
1198
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1199

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

    
1228
						$leftsubnet_spec[] = $leftsubnet_data;
1229

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

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

    
1248
						if (!isset($ph2ent['mobile'])) {
1249
							$rightsubnet_spec[] = $right_spec;
1250
						}
1251
					}
1252

    
1253
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1254
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1255
					}
1256

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

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

    
1330
					$reqids[] = $ph2ent['reqid'];
1331

    
1332
					if (!empty($ph2ent['lifetime'])) {
1333
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1334
							$ipseclifetime = intval($ph2ent['lifetime']);
1335
						}
1336
					}
1337

    
1338
				}
1339
			}
1340

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

    
1357
EOD;
1358

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

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

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

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

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

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

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

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

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

    
1492
	if (platform_booting()) {
1493
		echo "done\n";
1494
	}
1495

    
1496
	unlock($ipsecstartlock);
1497
	return count($filterdns_list);
1498
}
1499

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1588
	}
1589

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

    
1592
		case 'server':
1593

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

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

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

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

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

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

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

    
1625
				$mpdconf .=<<<EOD
1626

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

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

    
1640
			$mpdconf .=<<<EOD
1641

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

    
1668
EOD;
1669

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

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

    
1707
EOD;
1708

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

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

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

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

    
1731
			$mpdlinks = "";
1732

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

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

    
1743
EOD;
1744
			}
1745

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

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

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

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

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

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

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

    
1784
			break;
1785
	}
1786

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

    
1791
	return 0;
1792
}
1793

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

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

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

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

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

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

    
1818
	}
1819

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

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

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

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

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

    
1856
EOD;
1857

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

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

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

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

    
1872
				$mpdconf .=<<<EOD
1873

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

    
1879
EOD;
1880
			}
1881

    
1882
			$mpdconf .=<<<EOD
1883

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

    
1901
EOD;
1902

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

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

    
1935
EOD;
1936

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

    
1941
EOD;
1942
				}
1943
			}
1944

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

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

    
1956
			$mpdlinks = "";
1957

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

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

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

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

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

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

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

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

    
1996
			vpn_netgraph_support();
1997

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

    
2001
			break;
2002

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

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

    
2011
	return 0;
2012
}
2013

    
2014
?>
(59-59/67)