Project

General

Profile

Download (60 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2019 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2008 Shrew Soft Inc
10
 * All rights reserved.
11
 *
12
 * originally part of m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15
 *
16
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27
 */
28

    
29
require_once("ipsec.inc");
30
require_once("filter.inc");
31
require_once("auth.inc");
32

    
33
function vpn_update_daemon_loglevel($category, $level) {
34
	global $ipsec_log_cats, $ipsec_log_sevs;
35

    
36
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
37

    
38
		/* if you're setting to -1, need to add "--" to args */
39
		$argterm = "";
40
		if ($level == "-1") {
41
			$argterm = "--";
42
		}
43

    
44
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
45
	}
46
}
47

    
48
function vpn_logging_cfgtxt() {
49
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
50

    
51
	$cfgtext = array();
52
	$log_levels = ipsec_get_loglevels();
53
	foreach (array_keys($ipsec_log_cats) as $cat) {
54
		if (is_numeric($log_levels[$cat]) &&
55
		    in_array(intval($log_levels[$cat]), array_keys($ipsec_log_sevs), true)) {
56
			$cfgtext[] = "${cat} = {$log_levels[$cat]}";
57
		}
58
	}
59

    
60
	return $cfgtext;
61
}
62

    
63
/* include all configuration functions */
64
function vpn_ipsec_convert_to_modp($index) {
65

    
66
	$conversion = "";
67
	switch ($index) {
68
		case '1':
69
			$conversion = "modp768";
70
			break;
71
		case '2':
72
			$conversion = "modp1024";
73
			break;
74
		case '5':
75
			$conversion = "modp1536";
76
			break;
77
		case '14':
78
			$conversion = "modp2048";
79
			break;
80
		case '15':
81
			$conversion = "modp3072";
82
			break;
83
		case '16':
84
			$conversion = "modp4096";
85
			break;
86
		case '17':
87
			$conversion = "modp6144";
88
			break;
89
		case '18':
90
			$conversion = "modp8192";
91
			break;
92
		case '19':
93
			$conversion = "ecp256";
94
			break;
95
		case '20':
96
			$conversion = "ecp384";
97
			break;
98
		case '21':
99
			$conversion = "ecp521";
100
			break;
101
		case '22':
102
			$conversion = "modp1024s160";
103
			break;
104
		case '23':
105
			$conversion = "modp2048s224";
106
			break;
107
		case '24':
108
			$conversion = "modp2048s256";
109
			break;
110
		case '25':
111
			$conversion = "ecp192";
112
			break;
113
		case '26':
114
			$conversion = "ecp224";
115
			break;
116
		case '27':
117
			$conversion = "ecp224bp";
118
			break;
119
		case '28':
120
			$conversion = "ecp256bp";
121
			break;
122
		case '29':
123
			$conversion = "ecp384bp";
124
			break;
125
		case '30':
126
			$conversion = "ecp512bp";
127
			break;
128
		case '31':
129
			$conversion = "curve25519";
130
			break;
131
		case '32':
132
			$conversion = "curve448";
133
			break;
134
	}
135

    
136
	return $conversion;
137
}
138

    
139
function vpn_ipsec_configure($restart = false) {
140
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
141

    
142
	$ipsecstartlock = lock('ipsec', LOCK_EX);
143

    
144
	/* get the automatic ping_hosts.sh ready */
145
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
146
	touch("{$g['vardb_path']}/ipsecpinghosts");
147
	$ipsecpinghostsactive = false;
148

    
149
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
150
	filter_configure();
151

    
152
	$syscfg = $config['system'];
153
	$ipseccfg = $config['ipsec'];
154

    
155
	/* Configure asynchronous crypto. See https://redmine.pfsense.org/issues/8772 */
156
	set_sysctl(array('net.inet.ipsec.async_crypto' => (int) (isset($ipseccfg['async_crypto']) && ($ipseccfg['async_crypto'] == "enabled"))));
157

    
158
	if (!ipsec_enabled()) {
159
		/* try to stop charon */
160
		mwexec("/usr/local/sbin/ipsec stop");
161
		/* Stop dynamic monitoring */
162
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
163

    
164
		/* wait for process to die */
165
		sleep(2);
166

    
167
		/* IPSEC is off, shutdown enc interface.*/
168
		mwexec("/sbin/ifconfig enc0 down");
169

    
170
		unlock($ipsecstartlock);
171
		return 0;
172
	}
173

    
174
	$a_phase1 = $config['ipsec']['phase1'];
175
	$a_phase2 = $config['ipsec']['phase2'];
176
	$a_client = $config['ipsec']['client'];
177

    
178
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
179
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
180
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
181
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
182

    
183
	mwexec("/sbin/ifconfig enc0 up");
184
	$ipsec_vti_cleanup_ifs = array();
185

    
186
	/* needed for config files */
187
	safe_mkdir("{$g['varetc_path']}/ipsec");
188
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
189

    
190
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
191
	rmdir_recursive($capath);
192
	rmdir_recursive($keypath);
193
	rmdir_recursive($crlpath);
194
	rmdir_recursive($certpath);
195

    
196
	safe_mkdir($capath);
197
	safe_mkdir($keypath);
198
	safe_mkdir($crlpath);
199
	safe_mkdir($certpath);
200
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
201
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
202
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
203
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
204

    
205
	if (!file_exists("/usr/local/etc/ipsec.d") ||
206
	    !is_link("/usr/local/etc/ipsec.d")) {
207
		if (file_exists("/usr/local/etc/ipsec.d")) {
208
			rmdir_recursive("/usr/local/etc/ipsec.d");
209
		}
210
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
211
		    "/usr/local/etc/ipsec.d");
212
	}
213
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
214
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
215
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
216
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
217
		} else {
218
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
219
		}
220
		@symlink("/usr/local/etc/strongswan.d",
221
		    "{$g['varetc_path']}/ipsec/strongswan.d");
222
	}
223
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
224
	    !is_link("/usr/local/etc/strongswan.conf")) {
225
		@unlink("/usr/local/etc/strongswan.conf");
226
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
227
		    "/usr/local/etc/strongswan.conf");
228
	}
229
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
230
	    !is_link("/usr/local/etc/ipsec.conf")) {
231
		@unlink("/usr/local/etc/ipsec.conf");
232
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
233
		    "/usr/local/etc/ipsec.conf");
234
	}
235

    
236
	if (platform_booting()) {
237
		echo gettext("Configuring IPsec VPN... ");
238
	}
239

    
240
	/* resolve all local, peer addresses and setup pings */
241
	$ipmap = array();
242
	$rgmap = array();
243
	$filterdns_list = array();
244
	$aggressive_mode_psk = false;
245
	unset($iflist);
246
	$ifacesuse = array();
247
	$mobile_ipsec_auth = "";
248
	if (is_array($a_phase1) && count($a_phase1)) {
249

    
250
		$ipsecpinghosts = array();
251
		/* step through each phase1 entry */
252
		foreach ($a_phase1 as $ph1ent) {
253
			if (isset($ph1ent['disabled'])) {
254
				continue;
255
			}
256

    
257
			if (substr($ph1ent['interface'], 0, 4) == "_vip") {
258
				$vpninterface = get_configured_vip_interface($ph1ent['interface']);
259
				$ifacesuse[] = get_real_interface($vpninterface);
260
			} else {
261
				$vpninterface = get_failover_interface($ph1ent['interface']);
262
				if (substr($vpninterface, 0, 4) == "_vip") {
263
					$vpninterface = get_configured_vip_interface($vpninterface);
264
					$ifacesuse[] = get_real_interface($vpninterface);
265
				} elseif (!empty($vpninterface)) {
266
					$ifacesuse[] = $vpninterface;
267
				}
268
			}
269

    
270
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
271
				$aggressive_mode_psk = true;
272
			}
273

    
274
			$ikeid = $ph1ent['ikeid'];
275

    
276
			$ep = ipsec_get_phase1_src($ph1ent);
277
			/* When automatically guessing, use the first address. */
278
			$ep  = explode(',', $ep);
279
			$ep  = $ep[0];
280
			if (!is_ipaddr($ep)) {
281
				log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
282
				continue;
283
			}
284

    
285
			if (!in_array($ep, $ipmap)) {
286
				$ipmap[] = $ep;
287
			}
288

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

    
292
			if (isset ($ph1ent['mobile'])) {
293
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
294
				continue;
295
			}
296

    
297
			$rg = $ph1ent['remote-gateway'];
298

    
299
			if (!is_ipaddr($rg)) {
300
				$filterdns_list[] = "{$rg}";
301
				add_hostname_to_watch($rg);
302
				if (!platform_booting()) {
303
					$rg = resolve_retry($rg);
304
				}
305
				if (!is_ipaddr($rg)) {
306
					continue;
307
				}
308
			}
309
			if (array_search($rg, $rgmap)) {
310
				log_error(sprintf(gettext("The remote gateway %s already exists on another phase 1 entry"), $rg));
311
				continue;
312
			}
313
			$rgmap[$ph1ent['remote-gateway']] = $rg;
314

    
315
			$is_vti = false;
316
			if (is_array($a_phase2)) {
317
				/* step through each phase2 entry */
318
				foreach ($a_phase2 as $ph2ent) {
319
					if ($ph2ent['mode'] == 'vti') {
320
						$is_vti = true;
321
					}
322
					if (isset($ph2ent['disabled'])) {
323
						continue;
324
					}
325

    
326
					if ($ikeid != $ph2ent['ikeid']) {
327
						continue;
328
					}
329

    
330
					/* add an ipsec pinghosts entry */
331
					if ($ph2ent['pinghost']) {
332
						if (!is_array($iflist)) {
333
							$iflist = get_configured_interface_list();
334
						}
335
						$srcip = null;
336
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
337
						if (is_ipaddrv6($ph2ent['pinghost'])) {
338
							foreach ($iflist as $ifent => $ifname) {
339
								$interface_ip = get_interface_ipv6($ifent);
340
								if (!is_ipaddrv6($interface_ip)) {
341
									continue;
342
								}
343
								if (ip_in_subnet($interface_ip, $local_subnet)) {
344
									$srcip = $interface_ip;
345
									break;
346
								}
347
							}
348
						} else {
349
							foreach ($iflist as $ifent => $ifname) {
350
								$interface_ip = get_interface_ip($ifent);
351
								if (!is_ipaddrv4($interface_ip)) {
352
									continue;
353
								}
354
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
355
									$srcip = $interface_ip;
356
									break;
357
								}
358
							}
359
						}
360
						/* if no valid src IP was found in configured interfaces, try the vips */
361
						if (is_null($srcip)) {
362
							$viplist = get_configured_vip_list();
363
							foreach ($viplist as $vip => $address) {
364
								if (ip_in_subnet($address, $local_subnet)) {
365
									$srcip = $address;
366
									break;
367
								}
368
							}
369
						}
370
						$dstip = $ph2ent['pinghost'];
371
						if (is_ipaddrv6($dstip)) {
372
							$family = "inet6";
373
						} else {
374
							$family = "inet";
375
						}
376
						if (is_ipaddr($srcip)) {
377
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
378
							$ipsecpinghostsactive = true;
379
						}
380
					}
381
				}
382
			}
383
			if ($is_vti) {
384
				interface_ipsec_vti_configure($ph1ent);
385
			}
386
		}
387
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
388
		unset($ipsecpinghosts);
389
	}
390
	unset($iflist);
391
	/* Build a list of all IPsec interfaces configured on the firewall at the OS level */
392
	foreach (get_interface_arr() as $thisif) {
393
		if (substr($thisif, 0, 5) == "ipsec") {
394
			$ipsec_vti_cleanup_ifs[] = $thisif;
395
		}
396
	}
397

    
398
	$accept_unencrypted = "";
399
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
400
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
401
	}
402

    
403
	$stronconf = '';
404
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
405
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
406
	}
407

    
408
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
409
	if ($aggressive_mode_psk) {
410
		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.");
411
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
412
			$restart = true;
413
		}
414
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
415
	}
416

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

    
419
	$makebeforebreak = '';
420
	if (isset($config['ipsec']['makebeforebreak'])) {
421
		$makebeforebreak = 'make_before_break = yes';
422
	}
423

    
424
	if (isset($config['ipsec']['enableinterfacesuse'])) {
425
		if (!empty($ifacesuse)) {
426
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
427
		} else {
428
			$ifacesuse = '';
429
		}
430
	} else {
431
		$ifacesuse = '';
432
	}
433

    
434
	unset($stronconf);
435

    
436
	$strongswanlog = "";
437
	$ipsecloglevels = vpn_logging_cfgtxt();
438
	if (is_array($ipsecloglevels)) {
439
		foreach ($ipsecloglevels as $loglevel) {
440
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
441
		}
442
	}
443
	$strongswan = <<<EOD
444

    
445
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
446
starter {
447
	load_warning = no
448
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
449
}
450

    
451
charon {
452
# number of worker threads in charon
453
	threads = 16
454
	ikesa_table_size = 32
455
	ikesa_table_segments = 4
456
	init_limit_half_open = 1000
457
	install_routes = no
458
	load_modular = yes
459
	ignore_acquire_ts = yes
460
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
461
	{$accept_unencrypted}
462
	cisco_unity = {$unity_enabled}
463
	{$ifacesuse}
464
	{$makebeforebreak}
465

    
466
	syslog {
467
		identifier = charon
468
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
469
		daemon {
470
			ike_name = yes
471
{$strongswanlog}
472
		}
473
		# disable logging under auth so logs aren't duplicated
474
		auth {
475
			default = -1
476
		}
477
	}
478

    
479
	plugins {
480
		# Load defaults
481
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
482

    
483
		stroke {
484
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
485
		}
486

    
487
		unity {
488
			load = {$unity_enabled}
489
		}
490

    
491
		curve25519 {
492
			load = yes
493
		}
494

    
495
EOD;
496

    
497
	/* Find RADIUS servers designated for Mobile IPsec user auth */
498
	$radius_server_txt = "";
499
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
500
	foreach ($user_sources as $user_source) {
501
		$auth_server = auth_get_authserver($user_source);
502
		$nice_user_source = strtolower(preg_replace('/[\s\.]+/', '_', $user_source));
503
		if ($auth_server && $auth_server['type'] === 'radius') {
504
			$radius_server_txt .= <<<EOD
505
				{$nice_user_source} {
506
					address = {$auth_server['host']}
507
					secret = "{$auth_server['radius_secret']}"
508
					auth_port = {$auth_server['radius_auth_port']}
509
					acct_port = {$auth_server['radius_acct_port']}
510
				}
511

    
512
EOD;
513
		}
514
	}
515

    
516
	/* Activate RADIUS accounting if it was selected on the auth server view */
517
	$radius_accounting = "";
518
	if($auth_server && isset($auth_server['radius_acct_port'])){
519
		$radius_accounting = 'accounting = yes';
520
	}
521

    
522
	/* write an eap-radius config section if appropriate */
523
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
524
		$strongswan .= <<<EOD
525
		eap-radius {
526
			class_group = yes
527
			eap_start = no
528
			{$radius_accounting}
529
			servers {
530
{$radius_server_txt}
531
			}
532
		}
533

    
534
EOD;
535
	}
536

    
537
	if (is_array($a_client) && isset($a_client['enable'])) {
538
		$strongswan .= "\t\tattr {\n";
539

    
540
		$cfgservers = array();
541
		if (!empty($a_client['wins_server1'])) {
542
			$cfgservers[] = $a_client['wins_server1'];
543
		}
544
		if (!empty($a_client['wins_server2'])) {
545
			$cfgservers[] = $a_client['wins_server2'];
546
		}
547
		if (!empty($cfgservers)) {
548
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
549
		}
550
		unset($cfgservers);
551

    
552
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
553
			$net_list = '';
554
			foreach ($a_phase2 as $ph2ent) {
555
				if (isset($ph2ent['disabled'])) {
556
					continue;
557
				}
558

    
559
				if (!isset($ph2ent['mobile'])) {
560
					continue;
561
				}
562

    
563
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
564

    
565
				if (!empty($net_list)) {
566
					$net_list .= ",";
567
				}
568
				$net_list .= $localid;
569
			}
570

    
571
			if (!empty($net_list)) {
572
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
573
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
574
				unset($net_list);
575
			}
576
		}
577

    
578
		if (!empty($a_client['dns_domain'])) {
579
			$strongswan .= "\t\t\t# Search domain and default domain\n";
580
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
581
			if (empty($a_client['dns_split'])) {
582
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
583
			}
584
			$strongswan .= "\n";
585
		}
586

    
587
		if (!empty($a_client['dns_split'])) {
588
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
589
		}
590

    
591
		if (!empty($a_client['login_banner'])) {
592
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
593
		}
594

    
595
		if (isset($a_client['save_passwd'])) {
596
			$strongswan .= "\t\t\t28673 = 1\n";
597
		}
598

    
599
		if ($a_client['pfs_group']) {
600
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
601
		}
602
		$strongswan .= "\t\t}\n";
603

    
604
		if ($a_client['user_source'] != "none") {
605
			$strongswan .= "\t\txauth-generic {\n";
606
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
607
			$strongswan .= "\t\t\tauthcfg = ";
608
			$firstsed = 0;
609
			$authcfgs = explode(",", $a_client['user_source']);
610
			foreach ($authcfgs as $authcfg) {
611
				if ($firstsed > 0) {
612
					$strongswan .= ",";
613
				}
614
				if ($authcfg == "system") {
615
					$authcfg = "Local Database";
616
				}
617
				$strongswan .= $authcfg;
618
				$firstsed = 1;
619
			}
620
			$strongswan .= "\n";
621
			$strongswan .= "\t\t}\n";
622
		}
623
	}
624

    
625
	$strongswan .= "\n\t}\n}\n";
626
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
627
	unset($strongswan);
628

    
629
	/* write out CRL files */
630
	if (is_array($config['crl']) && count($config['crl'])) {
631
		foreach ($config['crl'] as $crl) {
632
			if (!isset($crl['text'])) {
633
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
634
				continue;
635
			}
636
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
637
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
638
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
639
				continue;
640
			}
641
		}
642
	}
643

    
644
	$pskconf = "";
645

    
646
	$vpncas = array();
647
	if (is_array($a_phase1) && count($a_phase1)) {
648
		foreach ($a_phase1 as $ph1ent) {
649

    
650
			if (isset($ph1ent['disabled'])) {
651
				continue;
652
			}
653

    
654
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
655
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
656
				$certline = '';
657

    
658
				$ikeid = $ph1ent['ikeid'];
659
				$cert = lookup_cert($ph1ent['certref']);
660

    
661
				if (!$cert) {
662
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
663
					continue;
664
				}
665

    
666
				/* add signing CA cert chain of server cert
667
				 * to the list of CAs to write
668
				 */
669
				$cachain = ca_chain_array($cert);
670
				if ($cachain && is_array($cachain)) {
671
					foreach ($cachain as $cacrt) {
672
						$vpncas[$cacrt['refid']] = $cacrt;
673
					}
674
				}
675

    
676
				@chmod($certpath, 0600);
677

    
678
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
679
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
680
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
681
					continue;
682
				}
683
				@chmod($ph1keyfile, 0600);
684

    
685
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
686
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
687
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
688
					@unlink($ph1keyfile);
689
					continue;
690
				}
691
				@chmod($ph1certfile, 0600);
692

    
693
				/* XXX" Traffic selectors? */
694
				$pskconf .= " : RSA {$ph1keyfile}\n";
695
			} else {
696
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
697
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
698

    
699
				$myid = trim($myid_data);
700

    
701
				if (empty($peerid_data)) {
702
					continue;
703
				}
704

    
705
				if ($myid_type == 'fqdn' && !empty($myid)) {
706
					$myid = "@{$myid}";
707
				}
708

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

    
711
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
712

    
713
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
714
					$peerid = "@{$peerid}";
715
				}
716

    
717
				if (!empty($ph1ent['pre-shared-key'])) {
718
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
719
					if (isset($ph1ent['mobile'])) {
720
						$pskconf .= "{$myid} %any : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
721
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
722
					}
723
				}
724
			}
725

    
726
			/* if the client authenticates with a cert add the
727
			 * client cert CA chain to the list of CAs to write
728
			 */
729
			if (in_array($ph1ent['authentication_method'],
730
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
731

    
732
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
733
					$thisca = lookup_ca($ph1ent['caref']);
734
					$vpncas[$ph1ent['caref']] = $thisca;
735

    
736
					/* follow chain up to root */
737
					$cachain = ca_chain_array($thisca);
738
					if ($cachain and is_array($cachain)) {
739
						foreach ($cachain as $cacrt) {
740
							$vpncas[$cacrt['refid']] = $cacrt;
741
						}
742
					}
743
				}
744
			}
745
		}
746
	}
747

    
748
	/* write the required CAs */
749
	foreach ($vpncas as $carefid => $cadata) {
750
		$cacrt = base64_decode($cadata['crt']);
751
		$cacrtattrs = openssl_x509_parse($cacrt);
752
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
753
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
754
			continue;
755
		}
756
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
757
		if (!@file_put_contents($cafilename, $cacrt)) {
758
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
759
				continue;
760
		}
761
	}
762

    
763
	/* Add user PSKs */
764
	if (is_array($config['system']) && is_array($config['system']['user'])) {
765
		foreach ($config['system']['user'] as $user) {
766
			if (!empty($user['ipsecpsk'])) {
767
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
768
			}
769
		}
770
		unset($user);
771
	}
772

    
773
	/* add PSKs for mobile clients */
774
	if (is_array($ipseccfg['mobilekey'])) {
775
		foreach ($ipseccfg['mobilekey'] as $key) {
776
			if ($key['ident'] == "allusers") {
777
				$key['ident'] = '%any';
778
			}
779
			if ($key['ident'] == "any") {
780
				$key['ident'] = '%any';
781
			}
782
			if (empty($key['type'])) {
783
				$key['type'] = 'PSK';
784
			}
785
			$pskconf .= " {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
786
		}
787
		unset($key);
788
	}
789

    
790
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
791
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
792
	unset($pskconf);
793

    
794
	$uniqueids = 'yes';
795
	if (!empty($config['ipsec']['uniqueids'])) {
796
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
797
			$uniqueids = $config['ipsec']['uniqueids'];
798
		}
799
	}
800
	$natfilterrules = false;
801
	/* begin ipsec.conf */
802
	$ipsecconf = "";
803
	$enablecompression = false;
804
	if (is_array($a_phase1) && count($a_phase1)) {
805

    
806
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
807
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
808

    
809
		if (isset($config['ipsec']['strictcrlpolicy'])) {
810
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
811
		}
812

    
813
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
814
			$bypassnets = array();
815
			if ($config['interfaces']['lan']) {
816
				$lanip = get_interface_ip("lan");
817
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
818
					$lansn = get_interface_subnet("lan");
819
					$lansa = gen_subnetv4($lanip, $lansn);
820
					if (!empty($lansa) && !empty($lansn)) {
821
						$bypassnets[] = "{$lansa}/{$lansn}";
822
					}
823
				}
824
				$lanip6 = get_interface_ipv6("lan");
825
				if (!empty($lanip6) && is_ipaddrv6($lanip6)) {
826
					$lansn6 = get_interface_subnetv6("lan");
827
					$lansa6 = gen_subnetv6($lanip6, $lansn6);
828
					if (!empty($lansa6) && !empty($lansn6)) {
829
						$bypassnets[] = "{$lansa6}/{$lansn6}";
830
					}
831
				}
832
			}
833
			if (!empty($bypassnets)) {
834
				$bypass = implode(',', $bypassnets);
835
				$ipsecconf .= <<<EOD
836

    
837
conn bypasslan
838
	leftsubnet = {$bypass}
839
	rightsubnet = {$bypass}
840
	authby = never
841
	type = passthrough
842
	auto = route
843

    
844
EOD;
845
			}
846
		}
847

    
848
		foreach ($a_phase1 as $ph1ent) {
849
			if (isset($ph1ent['disabled'])) {
850
				continue;
851
			}
852

    
853
			if ($ph1ent['mode'] == "aggressive") {
854
				$aggressive = "yes";
855
			} else {
856
				$aggressive = "no";
857
			}
858

    
859
			$ep = ipsec_get_phase1_src($ph1ent);
860
			if (!$ep) {
861
				continue;
862
			}
863

    
864
			$ikeid = $ph1ent['ikeid'];
865
			$keyexchange = "ikev1";
866
			$passive = "route";
867

    
868
			$closeaction = "";
869
			if (!empty($ph1ent['closeaction'])) {
870
				$closeaction = "closeaction = {$ph1ent['closeaction']}";
871
			}
872

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

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

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

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

    
945
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
946
			$leftid = ipsec_fixup_id($myid_type, $myid_data);
947
			if (!empty($leftid)) {
948
				$leftid = "leftid = {$leftid}";
949
			}
950

    
951
			$peerid_spec = '';
952
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
953
				// Only specify peer ID if we are not dealing with mobile PSK
954
			} else {
955
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
956
				$peerid_spec = ipsec_fixup_id($peerid_type, $peerid_data);
957
			}
958

    
959
			$ealgosp1 = '';
960
			if (is_array($ph1ent['encryption']['item'])) {
961
				$ciphers = "";
962
				foreach($ph1ent['encryption']['item'] as $p1enc) {
963
					if (!is_array($p1enc['encryption-algorithm']) ||
964
							empty($p1enc['encryption-algorithm']['name']) ||
965
							empty($p1enc['hash-algorithm'])) {
966
						continue;
967
					}
968
					$ciphers .= ",";
969
					$ciphers .= $p1enc['encryption-algorithm']['name'];
970
					$ealg_kl = $p1enc['encryption-algorithm']['keylen'];
971
					if ($ealg_kl) {
972
						$ciphers .= "{$ealg_kl}";
973
					}
974
					$ciphers .= "-{$p1enc['hash-algorithm']}";
975

    
976
					$modp = vpn_ipsec_convert_to_modp($p1enc['dhgroup']);
977
					if (!empty($modp)) {
978
						$ciphers .= "-{$modp}";
979
					}
980
				}
981
				$ciphers = substr($ciphers, 1);
982
				$ealgosp1 = "ike = {$ciphers}!";
983
			}
984

    
985
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
986
				if ($passive == "route") {
987
					$dpdline = "dpdaction = restart";
988
				} else {
989
					$dpdline = "dpdaction = clear";
990
				}
991
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
992
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
993
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
994
			} else {
995
				$dpdline = "dpdaction = none";
996
			}
997

    
998
			$ikelifeline = '';
999
			if ($ph1ent['lifetime']) {
1000
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1001
			}
1002

    
1003
			$rightsourceip = NULL;
1004
			$rightdnsserver = NULL;
1005
			if (isset($ph1ent['mobile'])) {
1006
				$rightsourceips = array();
1007
				if (!empty($a_client['pool_address'])) {
1008
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1009
				}
1010
				if (!empty($a_client['pool_address_v6'])) {
1011
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1012
				}
1013
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1014
					$rightsourceips[] = "%radius";
1015
				}
1016
				if (count($rightsourceips)) {
1017
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1018
				}
1019

    
1020
				$rightdnsservers = array();
1021
				if (!empty($a_client['dns_server1'])) {
1022
					$rightdnsservers[] = $a_client['dns_server1'];
1023
				}
1024
				if (!empty($a_client['dns_server2'])) {
1025
					$rightdnsservers[] = $a_client['dns_server2'];
1026
				}
1027
				if (!empty($a_client['dns_server3'])) {
1028
					$rightdnsservers[] = $a_client['dns_server3'];
1029
				}
1030
				if (!empty($a_client['dns_server4'])) {
1031
					$rightdnsservers[] = $a_client['dns_server4'];
1032
				}
1033

    
1034
				if (count($rightdnsservers)) {
1035
					$rightdnsserver = "\trightdns = " . implode(',', $rightdnsservers) . "\n";
1036
				}
1037
			}
1038

    
1039
			if (!empty($ph1ent['caref'])) {
1040
				$ca = lookup_ca($ph1ent['caref']);
1041
				if ($ca) {
1042
					$casubarr = cert_get_subject_array($ca['crt']);
1043
					$casub = "";
1044
					foreach ($casubarr as $casubfield) {
1045
						if (empty($casub)) {
1046
							$casub = "/";
1047
						}
1048
						/* The subfield value could be an array. To avoid duplicating code,
1049
						 * always make it an array then iterate.
1050
						 * See https://redmine.pfsense.org/issues/7929
1051
						 */
1052
						if (!is_array($casubfield['v'])) {
1053
							$casubfield['v'] = array($casubfield['v']);
1054
						}
1055
						foreach ($casubfield['v'] as $casubval) {
1056
							$casub .= "{$casubfield['a']}={$casubval}/";
1057
						}
1058
					}
1059

    
1060
				}
1061
			}
1062

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

    
1147
			$left_spec = $ep;
1148

    
1149
			if (isset($ph1ent['reauth_enable'])) {
1150
				$reauth = "reauth = no";
1151
			} else {
1152
				$reauth = "reauth = yes";
1153
			}
1154

    
1155
			if (isset($ph1ent['rekey_enable'])) {
1156
				$rekeyline = "rekey = no";
1157
			} else {
1158
				$rekeyline = "rekey = yes";
1159
				if(!empty($ph1ent['margintime'])){
1160
					$rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s";
1161
				}
1162
			}
1163

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

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

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

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

    
1199
					if (isset($ph2ent['disabled'])) {
1200
						continue;
1201
					}
1202

    
1203
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1204
						continue;
1205
					}
1206

    
1207
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1208
						$tunneltype = "type = tunnel";
1209
						$installpolicy = "installpolicy = yes";
1210

    
1211
						$localid_type = $ph2ent['localid']['type'];
1212
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1213

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

    
1242
						$leftsubnet_spec[] = $leftsubnet_data;
1243

    
1244
						if (!isset($ph2ent['mobile'])) {
1245
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1246
							$rightsubnet_spec[] = $tmpsubnet;
1247
						} else if (!empty($a_client['pool_address'])) {
1248
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1249
						}
1250
					} elseif ($ph2ent['mode'] == 'vti') {
1251
						$tunneltype = "";
1252
						$installpolicy = "installpolicy = no";
1253
						$passive = 'start';
1254

    
1255
						$localid_type = $ph2ent['localid']['type'];
1256
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1257
						$leftsubnet_spec[] = $leftsubnet_data;
1258

    
1259
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1260
						$rightsubnet_spec[] = $tmpsubnet;
1261
						$vtireq[] = $ph2ent['reqid'];
1262
					} else {
1263
						$tunneltype = "type = transport";
1264
						$installpolicy = "installpolicy = yes";
1265

    
1266
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1267
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1268
						    isset($ph1ent['mobile'])) {
1269
							$left_spec = "%any";
1270
						} else {
1271
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1272
							$leftsubnet_spec[] = $tmpsubnet;
1273
						}
1274

    
1275
						if (!isset($ph2ent['mobile'])) {
1276
							$rightsubnet_spec[] = $right_spec;
1277
						}
1278
					}
1279

    
1280
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1281
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1282
					}
1283

    
1284
					if ($ph2ent['protocol'] == 'esp') {
1285
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1286
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1287
								$ealg_id = $ealg['name'];
1288
								$ealg_kl = $ealg['keylen'];
1289

    
1290
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
1291
									if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1292
										require_once("ipsec.inc");
1293
									}
1294
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1295
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1296
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1297
									/* XXX: in some cases where include ordering is suspect these variables
1298
									 * are somehow 0 and we enter this loop forever and timeout after 900
1299
									 * seconds wrecking bootup */
1300
									if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1301
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1302
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1303
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1304
													$halgo = str_replace('hmac_', '', $halgo);
1305
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1306
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1307
													if (!empty($modp)) {
1308
														$tmpealgo .= "-{$modp}";
1309
													}
1310
													if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1311
														$ealgoESPsp2arr[] = $tmpealgo;
1312
													}
1313
												}
1314
											} else {
1315
												$tmpealgo = "{$ealg_id}{$keylen}";
1316
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1317
												if (!empty($modp)) {
1318
													$tmpealgo .= "-{$modp}";
1319
												}
1320
												if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1321
													$ealgoESPsp2arr[] = $tmpealgo;
1322
												}
1323
											}
1324
										}
1325
									}
1326
								} else {
1327
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1328
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1329
											$halgo = str_replace('hmac_', '', $halgo);
1330
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1331
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1332
											if (!empty($modp)) {
1333
												$tmpealgo .= "-{$modp}";
1334
											}
1335
											if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1336
												$ealgoESPsp2arr[] = $tmpealgo;
1337
											}
1338
										}
1339
									} else {
1340
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
1341
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1342
										if (!empty($modp)) {
1343
											$tmpealgo .= "-{$modp}";
1344
										}
1345
										if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1346
											$ealgoESPsp2arr[] = $tmpealgo;
1347
										}
1348
									}
1349
								}
1350
							}
1351
						}
1352
					} else if ($ph2ent['protocol'] == 'ah') {
1353
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1354
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1355
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1356
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1357
								if (!empty($modp)) {
1358
									$tmpAHalgo = "-{$modp}";
1359
								}
1360
								if (!in_array($tmpAHalgo, $ealgoAHsp2arr)) {
1361
									$ealgoAHsp2arr[] = $tmpAHalgo;
1362
								}
1363
							}
1364
						}
1365
					}
1366

    
1367
					$reqids[] = $ph2ent['reqid'];
1368
					if ($ph2ent['mode'] != 'vti') {
1369
						$vtireq[] = null;
1370
					}
1371

    
1372
					if (!empty($ph2ent['lifetime'])) {
1373
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1374
							$ipseclifetime = intval($ph2ent['lifetime']);
1375
						}
1376
					}
1377

    
1378
				}
1379
			}
1380

    
1381
			$ipsecconnect =<<<EOD
1382
	fragmentation = yes
1383
	keyexchange = {$keyexchange}
1384
	{$reauth}
1385
	{$forceencaps}
1386
	{$mobike}
1387
	{$tfc}
1388
	{$rekeyline}
1389
	{$installpolicy}
1390
	{$tunneltype}
1391
	{$dpdline}
1392
	{$closeaction}
1393
	auto = {$passive}
1394
	left = {$left_spec}
1395
	right = {$right_spec}
1396
	{$leftid}
1397

    
1398
EOD;
1399

    
1400
			/* Disable ipcomp for now. redmine #6167
1401
			if (isset($config['ipsec']['compression'])) {
1402
				$ipsecconnect .= "\tcompress = yes\n";
1403
				$enablecompression = true;
1404
			} */
1405
			if (!empty($ikelifeline)) {
1406
				$ipsecconnect .= "\t{$ikelifeline}\n";
1407
			}
1408
			if ($ipseclifetime > 0) {
1409
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1410
			}
1411
			if (!empty($rightsourceip)) {
1412
				$ipsecconnect .= "{$rightsourceip}";
1413
			}
1414
			if (!empty($rightdnsserver)) {
1415
				$ipsecconnect .= "{$rightdnsserver}";
1416
			}
1417
			if (!empty($ealgosp1)) {
1418
				$ipsecconnect .= "\t{$ealgosp1}\n";
1419
			}
1420
			if (!empty($ealgoAHsp2arr)) {
1421
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1422
			}
1423
			if (!empty($ealgoESPsp2arr)) {
1424
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1425
			}
1426
			if (!empty($authentication)) {
1427
				$ipsecconnect .= "\t{$authentication}\n";
1428
			}
1429
			if (!empty($peerid_spec)) {
1430
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1431
			}
1432
			if ($keyexchange != 'ikev2') {
1433
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1434
			}
1435

    
1436
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1437
				if (!empty($rightsubnet_spec)) {
1438
					$ipsecfin = '';
1439
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1440
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1441
						//if (!empty($reqids[$idx])) {
1442
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1443
						//}
1444
						$rightadd = "";
1445
						$leftadd = "";
1446
						if (!empty($vtireq[$idx])) {
1447
							$ipsecfin .= "\treqid = {$ph1ent['ikeid']}00{$idx}\n";
1448
							/* This interface will be a valid IPsec interface, so remove it from the cleanup list. */
1449
							$ipsec_vti_cleanup_ifs = array_diff($ipsec_vti_cleanup_ifs, array("ipsec{$ph1ent['ikeid']}00{$idx}"));
1450
							$rightadd = ",0.0.0.0/0";
1451
							$leftadd = ",0.0.0.0/0";
1452
						}
1453
						$ipsecfin .= $ipsecconnect;
1454
						$ipsecfin .= "\trightsubnet = {$rsubnet}{$rightadd}\n";
1455
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "{$leftadd}\n";
1456
					}
1457
				} else {
1458
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1459
				}
1460
			} else {
1461
				if (isset($ph1ent['mobile'])) {
1462
					$ipsecfin = "\nconn con-mobile\n";
1463
				}
1464
				else {
1465
					$ipsecfin = "\nconn con{$ph1ent['ikeid']}000\n";
1466
				}
1467
				//if (!empty($reqids[$idx])) {
1468
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1469
				//}
1470
				$rightadd = "";
1471
				$leftadd = "";
1472
				if (!empty($vtireq[0])) {
1473
					$ipsecfin .= "\treqid = {$ph1ent['ikeid']}000\n";
1474
					/* This interface will be a valid IPsec interface, so remove it from the cleanup list. */
1475
					$ipsec_vti_cleanup_ifs = array_diff($ipsec_vti_cleanup_ifs, array("ipsec{$ph1ent['ikeid']}000"));
1476
					$rightadd = ",0.0.0.0/0";
1477
					$leftadd = ",0.0.0.0/0";
1478
				}
1479
				$ipsecfin .= $ipsecconnect;
1480
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1481
					$tempsubnets = array();
1482
					foreach ($rightsubnet_spec as $rightsubnet) {
1483
						$tempsubnets[$rightsubnet] = $rightsubnet;
1484
					}
1485
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "{$rightadd}\n";
1486
					unset($tempsubnets, $rightsubnet);
1487
				}
1488
				if (!empty($leftsubnet_spec)) {
1489
					$tempsubnets = array();
1490
					foreach ($leftsubnet_spec as $leftsubnet) {
1491
						$tempsubnets[$leftsubnet] = $leftsubnet;
1492
					}
1493
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "{$leftadd}\n";
1494
					unset($tempsubnets, $leftsubnet);
1495
				}
1496
			}
1497
			$ipsecconf .= $ipsecfin;
1498
			unset($ipsecfin);
1499
		}
1500
	}
1501

    
1502
	$a_mobilekey = $config['ipsec']['mobilekey'];
1503

    
1504
	if (is_array($a_phase1) && count($a_phase1)) {
1505
		foreach ($a_phase1 as $ph1ent) {
1506
			if (!isset($ph1ent['mobile'])) {
1507
				continue;
1508
			}
1509
			if (isset($ph1ent['disabled'])) {
1510
				continue;
1511
			}
1512

    
1513
			if (is_array($a_mobilekey) && count($a_mobilekey)) {
1514
				$ipsecfin = '';
1515
				$mobilekey_counter = 1;
1516
				foreach ($a_mobilekey as $mkent) {
1517
					if ($mkent['type'] != "EAP") {
1518
						continue;
1519
					}
1520

    
1521
					if (!isset($mkent['ident_type']) || !isset($mkent['pool_address']) || !isset($mkent['pool_netbits'])) {
1522
						continue;
1523
					}
1524

    
1525
					if (strlen($mkent['pool_address']) < 1 || !is_ipaddr($mkent['pool_address'])) {
1526
						continue;
1527
					}
1528
					$clientid = ($mkent['ident_type'] == "none") ? "\"{$mkent['ident']}\"" : "{$mkent['ident_type']}:{$mkent['ident']}";
1529
					$clienteapid = ($ph1ent['authentication_method'] == "eap-mschapv2") ? $clientid : '%identity';
1530
					$ipsecfin .= "\nconn mobile-{$mobilekey_counter}\n";
1531
					$ipsecfin .= "\talso = con-mobile\n";
1532
					$ipsecfin .= "\teap_identity = {$clienteapid}\n";
1533
					$ipsecfin .= "\trightsourceip = {$mkent['pool_address']}/{$mkent['pool_netbits']}\n";
1534

    
1535
					if (isset($mkent['dns_address']) && strlen($mkent['dns_address']) > 0 && is_ipaddr($mkent['dns_address'])) {
1536
						$ipsecfin .= "\trightdns = {$mkent['dns_address']}\n";
1537
					}
1538

    
1539
					$ipsecfin .= "\trightid = {$clientid}\n";
1540

    
1541
					// optional: define left|rightid more granular
1542
					// supported: ipv4, ipv6, rfc822, email, userfqdn, fqdn, dns, asn1dn, asn1gn, keyid
1543
					// example: $ipsecfin = "\trightid = email:your@email.address\n";
1544

    
1545
					// note: comma separated list for access restriction, regardless of firewall rules
1546
					// example: $ipsecfin = "\tleftsubnet = 1.1.1.1/32,1.1.1.2/32,2.2.2.0/24\n";
1547

    
1548
					$mobilekey_counter++;
1549
				}
1550
				$ipsecconf .= $ipsecfin;
1551
				unset($ipsecfin);
1552
				unset($mobilekey_counter);
1553
			}
1554
		}
1555
	}
1556

    
1557
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1558
	unset($ipsecconf);
1559
	/* end ipsec.conf */
1560

    
1561
	foreach ($ipsec_vti_cleanup_ifs as $cleanif) {
1562
		if (does_interface_exist($cleanif)) {
1563
			mwexec("/sbin/ifconfig " . escapeshellarg($cleanif) . " destroy", false);
1564
		}
1565
	}
1566

    
1567
	if ($enablecompression === true) {
1568
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1569
	} else {
1570
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1571
	}
1572

    
1573
	/* manage process */
1574
	if ($restart === true) {
1575
		mwexec("/usr/local/sbin/ipsec restart", false);
1576
	} else {
1577
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1578
			/* Update configuration changes */
1579
			/* Read secrets */
1580
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1581
			mwexec("/usr/local/sbin/ipsec reload", false);
1582
		} else {
1583
			mwexec("/usr/local/sbin/ipsec start", false);
1584
		}
1585
	}
1586

    
1587
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1588
	if ($ipsecpinghostsactive == true) {
1589
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1590
	}
1591

    
1592
	if ($natfilterrules == true) {
1593
		filter_configure();
1594
	}
1595
	/* start filterdns, if necessary */
1596
	if (count($filterdns_list) > 0) {
1597
		$interval = 60;
1598
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1599
			$interval = $ipseccfg['dns-interval'];
1600
		}
1601

    
1602
		$hostnames = "";
1603
		array_unique($filterdns_list);
1604
		foreach ($filterdns_list as $hostname) {
1605
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1606
		}
1607
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1608
		unset($hostnames);
1609

    
1610
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1611
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1612
		} else {
1613
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1614
		}
1615
	} else {
1616
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1617
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1618
	}
1619

    
1620
	if (platform_booting()) {
1621
		echo "done\n";
1622
	}
1623

    
1624
	unlock($ipsecstartlock);
1625
	return count($filterdns_list);
1626
}
1627

    
1628
/*
1629
 * Forcefully restart IPsec
1630
 * This is required for when dynamic interfaces reload
1631
 * For all other occasions the normal vpn_ipsec_configure()
1632
 * will gracefully reload the settings without restarting
1633
 */
1634
function vpn_ipsec_force_reload($interface = "") {
1635
	global $g, $config;
1636

    
1637
	if (!ipsec_enabled()) {
1638
		return;
1639
	}
1640

    
1641
	$ipseccfg = $config['ipsec'];
1642

    
1643
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1644
		$found = false;
1645
		foreach ($ipseccfg['phase1'] as $ipsec) {
1646
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1647
				$found = true;
1648
				break;
1649
			}
1650
		}
1651
		if (!$found) {
1652
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1653
			return;
1654
		}
1655
	}
1656

    
1657
	/* If we get this far then we need to take action. */
1658
	log_error(gettext("Forcefully reloading IPsec"));
1659
	vpn_ipsec_configure();
1660
}
1661

    
1662
/* master setup for vpn (mpd) */
1663
function vpn_setup() {
1664
	/* start pppoe server */
1665
	vpn_pppoes_configure();
1666

    
1667
	/* setup l2tp */
1668
	vpn_l2tp_configure();
1669
}
1670

    
1671
function vpn_netgraph_support() {
1672
	$iflist = get_configured_interface_list();
1673
	foreach ($iflist as $iface) {
1674
		$realif = get_real_interface($iface);
1675
		/* Get support for netgraph(4) from the nic */
1676
		$ifinfo = pfSense_get_interface_addresses($realif);
1677
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1678
			pfSense_ngctl_attach(".", $realif);
1679
		}
1680
	}
1681
}
1682

    
1683
function vpn_pppoes_configure() {
1684
	global $config;
1685

    
1686
	if (is_array($config['pppoes']['pppoe'])) {
1687
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1688
			vpn_pppoe_configure($pppoe);
1689
		}
1690
	}
1691
}
1692

    
1693
function vpn_pppoe_configure(&$pppoecfg) {
1694
	global $config, $g;
1695

    
1696
	$syscfg = $config['system'];
1697

    
1698
	/* create directory if it does not exist */
1699
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1700
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1701
	}
1702

    
1703
	if (platform_booting()) {
1704
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1705
			return 0;
1706
		}
1707

    
1708
		echo gettext("Configuring PPPoE Server service... ");
1709
	} else {
1710
		/* kill mpd */
1711
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1712

    
1713
		/* wait for process to die */
1714
		sleep(2);
1715

    
1716
	}
1717

    
1718
	switch ($pppoecfg['mode']) {
1719

    
1720
		case 'server':
1721

    
1722
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1723

    
1724
			if ($pppoecfg['paporchap'] == "chap") {
1725
				$paporchap = "set link enable chap";
1726
			} else {
1727
				$paporchap = "set link enable pap";
1728
			}
1729

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

    
1737
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
1738
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1739
				$issue_ip_type .= "0.0.0.0/0";
1740
			} else {
1741
				$issue_ip_type .= "ippool p0";
1742
			}
1743

    
1744
			$ippool_p0 = ip_after($pppoecfg['remoteip'], $pppoecfg['n_pppoe_units'] - 1);
1745

    
1746
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1747
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1748
			} else {
1749
				$pppoemaxlogins = 1;
1750
			}
1751

    
1752
			$ipcp_dns = '';
1753
			if (!empty($pppoecfg['dns1'])) {
1754
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
1755
				if (!empty($pppoecfg['dns2'])) {
1756
					$ipcp_dns .= " " . $pppoecfg['dns2'];
1757
				}
1758
			} elseif (isset($config['dnsmasq']['enable']) ||
1759
			    isset ($config['unbound']['enable'])) {
1760
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1761
				if ($syscfg['dnsserver'][0]) {
1762
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1763
				}
1764
			} elseif (is_array($syscfg['dnsserver']) &&
1765
			    ($syscfg['dnsserver'][0])) {
1766
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1767
			}
1768

    
1769
			$mpdconf = <<<EOD
1770
startup:
1771

    
1772
poes:
1773
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
1774

    
1775
	create bundle template poes_b
1776
	set bundle enable compression
1777

    
1778
	set ccp yes mppc
1779
	set mppc yes e40
1780
	set mppc yes e128
1781
	set mppc yes stateless
1782

    
1783
	set iface group pppoe
1784
	set iface up-script /usr/local/sbin/vpn-linkup-poes
1785
	set iface down-script /usr/local/sbin/vpn-linkdown-poes
1786
	set iface idle 0
1787
	set iface disable on-demand
1788
	set iface disable proxy-arp
1789
	set iface enable tcpmssfix
1790
	set iface mtu 1500
1791

    
1792
	set ipcp no vjcomp
1793
	{$issue_ip_type}
1794
	{$ipcp_dns}
1795

    
1796
	create link template poes_l pppoe
1797
	set link action bundle poes_b
1798

    
1799
	set auth max-logins {$pppoemaxlogins}
1800

    
1801
	set pppoe iface {$pppoe_interface}
1802

    
1803
	set link no multilink
1804
	set link no pap chap
1805
	{$paporchap}
1806
	set link keep-alive 60 180
1807
	set link max-redial -1
1808
	set link mru 1492
1809
	set link latency 1
1810
	set link enable incoming
1811

    
1812
EOD;
1813

    
1814
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1815
				$radiusport = "";
1816
				$radiusacctport = "";
1817
				if (isset($pppoecfg['radius']['server']['port'])) {
1818
					$radiusport = $pppoecfg['radius']['server']['port'];
1819
				}
1820
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1821
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1822
				}
1823
				$mpdconf .=<<<EOD
1824
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1825
	set radius retries 3
1826
	set radius timeout 10
1827
	set auth enable radius-auth
1828

    
1829
EOD;
1830

    
1831
				if (isset ($pppoecfg['radius']['accounting'])) {
1832
					$mpdconf .=<<<EOD
1833
	set auth enable radius-acct
1834

    
1835
EOD;
1836
				}
1837
				if (!empty($pppoecfg['radius']['nasip'])) {
1838
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1839
				}
1840
			}
1841

    
1842
			fwrite($fd, $mpdconf);
1843
			fclose($fd);
1844
			unset($mpdconf);
1845

    
1846
			if ($pppoecfg['username']) {
1847
				/* write mpd.secret */
1848
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1849
				if (!$fd) {
1850
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1851
					return 1;
1852
				}
1853

    
1854
				$mpdsecret = "\n\n";
1855

    
1856
				if (!empty($pppoecfg['username'])) {
1857
					$item = explode(" ", $pppoecfg['username']);
1858
					foreach ($item as $userdata) {
1859
						$data = explode(":", $userdata);
1860
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1861
					}
1862
				}
1863

    
1864
				fwrite($fd, $mpdsecret);
1865
				fclose($fd);
1866
				unset($mpdsecret);
1867
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1868
			}
1869

    
1870
			/* Check if previous instance is still up */
1871
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1872
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1873
			}
1874

    
1875
			/* Get support for netgraph(4) from the nic */
1876
			pfSense_ngctl_attach(".", $pppoe_interface);
1877
			/* fire up mpd */
1878
			mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1879

    
1880
			break;
1881
	}
1882

    
1883
	if (platform_booting()) {
1884
		echo gettext("done") . "\n";
1885
	}
1886

    
1887
	return 0;
1888
}
1889

    
1890
function vpn_l2tp_configure() {
1891
	global $config, $g;
1892

    
1893
	$syscfg = $config['system'];
1894
	$l2tpcfg = $config['l2tp'];
1895

    
1896
	/* create directory if it does not exist */
1897
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1898
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1899
	}
1900

    
1901
	if (platform_booting()) {
1902
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1903
			return 0;
1904
		}
1905

    
1906
		echo gettext("Configuring l2tp VPN service... ");
1907
	} else {
1908
		/* kill mpd */
1909
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1910

    
1911
		/* wait for process to die */
1912
		sleep(8);
1913

    
1914
	}
1915

    
1916
	/* make sure l2tp-vpn directory exists */
1917
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1918
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1919
	}
1920

    
1921
	switch ($l2tpcfg['mode']) {
1922

    
1923
		case 'server':
1924
			$l2tp_listen="";
1925
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1926
			if (is_ipaddrv4($ipaddr)) {
1927
				$l2tp_listen="set l2tp self $ipaddr";
1928
			}
1929

    
1930
			switch ($l2tpcfg['paporchap']) {
1931
				case 'chap':
1932
					$paporchap = "set link enable chap";
1933
					break;
1934
				case 'chap-msv2':
1935
					$paporchap = "set link enable chap-msv2";
1936
					break;
1937
				default:
1938
					$paporchap = "set link enable pap";
1939
					break;
1940
			}
1941

    
1942
			/* write mpd.conf */
1943
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1944
			if (!$fd) {
1945
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1946
				return 1;
1947
			}
1948

    
1949
			$ippool_p0 = ip_after($l2tpcfg['remoteip'], $l2tpcfg['n_l2tp_units'] - 1);
1950

    
1951
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
1952
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
1953
				$issue_ip_type .= "0.0.0.0/0";
1954
			} else {
1955
				$issue_ip_type .= "ippool p0";
1956
			}
1957

    
1958
			$ipcp_dns = '';
1959
			if (is_ipaddr($l2tpcfg['dns1'])) {
1960
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
1961
				if (is_ipaddr($l2tpcfg['dns2'])) {
1962
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
1963
				}
1964
			} elseif (isset ($config['dnsmasq']['enable']) ||
1965
			    isset ($config['unbound']['enable'])) {
1966
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1967
				if ($syscfg['dnsserver'][0]) {
1968
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1969
				}
1970
			} elseif (is_array($syscfg['dnsserver']) &&
1971
			    ($syscfg['dnsserver'][0])) {
1972
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1973
			}
1974

    
1975
			$mpdconf =<<<EOD
1976

    
1977
startup:
1978

    
1979
l2tps:
1980
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
1981

    
1982
	create bundle template l2tp_b
1983
	set bundle enable compression
1984
	set bundle yes crypt-reqd
1985

    
1986
	set ccp yes mppc
1987

    
1988
	set iface name l2tp
1989
	set iface group l2tp
1990
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
1991
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
1992
	set iface disable on-demand
1993
	set iface enable proxy-arp
1994

    
1995
	set ipcp yes vjcomp
1996
	{$issue_ip_type}
1997
	{$ipcp_dns}
1998

    
1999
	create link template l2tp_l l2tp
2000
	set link action bundle l2tp_b
2001

    
2002
	set link yes acfcomp protocomp
2003
	set link enable multilink
2004
	set link no pap chap chap-msv2
2005
	{$paporchap}
2006
	{$l2tp_listen}
2007
	set link keep-alive 10 180
2008
	set link enable incoming
2009

    
2010
EOD;
2011

    
2012

    
2013
			if (isset ($l2tpcfg['radius']['enable'])) {
2014
				$mpdconf .=<<<EOD
2015
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
2016
	set radius retries 3
2017
	set radius timeout 10
2018
	set auth disable internal
2019
	set auth enable radius-auth
2020

    
2021
EOD;
2022

    
2023
				if (isset ($l2tpcfg['radius']['accounting'])) {
2024
					$mpdconf .=<<<EOD
2025
	set auth enable radius-acct
2026

    
2027
EOD;
2028
				}
2029
			}
2030

    
2031
			fwrite($fd, $mpdconf);
2032
			fclose($fd);
2033
			unset($mpdconf);
2034

    
2035
			/* write mpd.secret */
2036
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
2037
			if (!$fd) {
2038
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
2039
				return 1;
2040
			}
2041

    
2042
			$mpdsecret = "\n\n";
2043

    
2044
			if (is_array($l2tpcfg['user'])) {
2045
				foreach ($l2tpcfg['user'] as $user) {
2046
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2047
				}
2048
			}
2049

    
2050
			fwrite($fd, $mpdsecret);
2051
			fclose($fd);
2052
			unset($mpdsecret);
2053
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2054

    
2055
			vpn_netgraph_support();
2056

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

    
2060
			break;
2061

    
2062
		case 'redir':
2063
			break;
2064
	}
2065

    
2066
	if (platform_booting()) {
2067
		echo "done\n";
2068
	}
2069

    
2070
	return 0;
2071
}
2072

    
2073
?>
(54-54/59)