Project

General

Profile

Download (58.6 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 Electric Sheep Fencing, LLC
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 ($ph1ent['protocol'] == 'inet') {
904
					if (substr($ph1ent['interface'], 0, 4) == "_vip") {
905
						$vpninterface = get_configured_vip_interface($ph1ent['interface']);
906
						$ifacesuse = get_real_interface($vpninterface);
907
					} else {
908
						$ifacesuse = get_failover_interface($ph1ent['interface']);
909
						if (substr($ifacesuse, 0, 4) == "_vip") {
910
							$vpninterface = get_configured_vip_interface($ifacesuse);
911
							$ifacesuse = get_real_interface($vpninterface);
912
						} else {
913
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
914
						}
915
					}
916

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

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

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

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

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

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

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

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

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

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

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

    
1062
				}
1063
			}
1064

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

    
1149
			$left_spec = $ep;
1150

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

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

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

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

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

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

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

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

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

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

    
1238
						$leftsubnet_spec[] = $leftsubnet_data;
1239

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

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

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

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

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

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

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

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

    
1348
				}
1349
			}
1350

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

    
1367
EOD;
1368

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1598
	}
1599

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

    
1602
		case 'server':
1603

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

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

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

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

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

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

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

    
1635
				$mpdconf .=<<<EOD
1636

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

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

    
1650
			$mpdconf .=<<<EOD
1651

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

    
1678
EOD;
1679

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

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

    
1717
EOD;
1718

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

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

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

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

    
1741
			$mpdlinks = "";
1742

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

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

    
1753
EOD;
1754
			}
1755

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

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

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

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

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

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

    
1789
			/* Get support for netgraph(4) from the nic */
1790
			pfSense_ngctl_attach(".", $pppoe_interface);
1791
			/* fire up mpd */
1792
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1793

    
1794
			break;
1795
	}
1796

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

    
1801
	return 0;
1802
}
1803

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

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

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

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

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

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

    
1828
	}
1829

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

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

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

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

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

    
1866
EOD;
1867

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

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

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

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

    
1882
				$mpdconf .=<<<EOD
1883

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

    
1889
EOD;
1890
			}
1891

    
1892
			$mpdconf .=<<<EOD
1893

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

    
1911
EOD;
1912

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

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

    
1945
EOD;
1946

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

    
1951
EOD;
1952
				}
1953
			}
1954

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

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

    
1966
			$mpdlinks = "";
1967

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

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

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

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

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

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

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

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

    
2006
			vpn_netgraph_support();
2007

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

    
2011
			break;
2012

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

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

    
2021
	return 0;
2022
}
2023

    
2024
?>
(57-57/65)